1

I'm writing a directive which has dependencies on TemplateRef<any> and ViewContainerRef. But my directive cannot get these dependencies injected in. The following are all my code:

main.ts

import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app.module';
platformBrowserDynamic().bootstrapModule(AppModule);

app.module.ts

import { NgModule }      from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { HelloWorld } from './HelloWorld.directive';

@NgModule({
    imports: [BrowserModule],
    declarations: [AppComponent, HelloWorld],
    bootstrap: [AppComponent]
})
export class AppModule { }

app.component.ts

import { Component } from '@angular/core';

@Component({
    selector: 'my-app',
    template: ` 
           Hello world!
           <template [lcngHw]="true"><div></div></template>
           `
})
export class AppComponent {
}

HelloWorld.directive.ts

import { Directive } from '@angular/core';
import { Input } from '@angular/core';

import { TemplateRef, ViewContainerRef } from '@angular/core';

@Directive({
    selector: '[lcngHw]'
})
export class HelloWorld{
    constructor(private tf: TemplateRef<any>, private vc: ViewContainerRef){

    }

    @Input()
    set lcngHw(value: boolean) {
        if (value) {
            this.vc.createEmbeddedView(this.tf);
        }
        else {
            this.vc.clear();
        }
    }
}

And here is my transpiled HelloWorld.directive.js:

"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var core_1 = require('@angular/core');
var core_2 = require('@angular/core');
var HelloWorld = (function () {
    function HelloWorld(tf, vc) {
        this.tf = tf;
        this.vc = vc;
    }
    Object.defineProperty(HelloWorld.prototype, "lcngHw", {
        set: function (value) {
            if (value) {
                this.vc.createEmbeddedView(this.tf);
            }
            else {
                this.vc.clear();
            }
        },
        enumerable: true,
        configurable: true
    });
    __decorate([
        core_2.Input()
    ], HelloWorld.prototype, "lcngHw", null);
    HelloWorld = __decorate([
        core_1.Directive({
            selector: '[lcngHw]'
        })
    ], HelloWorld);
    return HelloWorld;
}());
exports.HelloWorld = HelloWorld;

Then I run my app, and I get the following error:

Error: (SystemJS) Can't resolve all parameters for HelloWorld: (?, ?).

Error: Can't resolve all parameters for HelloWorld: (?, ?). at CompileMetadataResolver.getDependenciesMetadata (http://localhost:5000/node_modules/@angular/compiler/bundles/compiler.umd.js:14268:21) at CompileMetadataResolver.getTypeMetadata (http://localhost:5000/node_modules/@angular/compiler/bundles/compiler.umd.js:14169:28) at CompileMetadataResolver.getDirectiveMetadata (http://localhost:5000/node_modules/@angular/compiler/bundles/compiler.umd.js:13944:30) at eval (http://localhost:5000/node_modules/@angular/compiler/bundles/compiler.umd.js:14037:51) at Array.forEach (native) at CompileMetadataResolver.getNgModuleMetadata (http://localhost:5000/node_modules/@angular/compiler/bundles/compiler.umd.js:14031:51) at RuntimeCompiler._compileComponents (http://localhost:5000/node_modules/@angular/compiler/bundles/compiler.umd.js:16721:49) at RuntimeCompiler._compileModuleAndComponents (http://localhost:5000/node_modules/@angular/compiler/bundles/compiler.umd.js:16659:39) at RuntimeCompiler.compileModuleAsync (http://localhost:5000/node_modules/@angular/compiler/bundles/compiler.umd.js:16650:23) at PlatformRef_._bootstrapModuleWithZone (http://localhost:5000/node_modules/@angular/core/bundles/core.umd.js:6707:29) Evaluating http://localhost:5000/ViewContainerRefApp/main.js Error loading http://localhost:5000/ViewContainerRefApp/main.js at CompileMetadataResolver.getDependenciesMetadata (http://localhost:5000/node_modules/@angular/compiler/bundles/compiler.umd.js:14268:21) at CompileMetadataResolver.getTypeMetadata (http://localhost:5000/node_modules/@angular/compiler/bundles/compiler.umd.js:14169:28) at CompileMetadataResolver.getDirectiveMetadata (http://localhost:5000/node_modules/@angular/compiler/bundles/compiler.umd.js:13944:30) at eval (http://localhost:5000/node_modules/@angular/compiler/bundles/compiler.umd.js:14037:51) at Array.forEach (native) at CompileMetadataResolver.getNgModuleMetadata (http://localhost:5000/node_modules/@angular/compiler/bundles/compiler.umd.js:14031:51) at RuntimeCompiler._compileComponents (http://localhost:5000/node_modules/@angular/compiler/bundles/compiler.umd.js:16721:49) at RuntimeCompiler._compileModuleAndComponents (http://localhost:5000/node_modules/@angular/compiler/bundles/compiler.umd.js:16659:39) at RuntimeCompiler.compileModuleAsync (http://localhost:5000/node_modules/@angular/compiler/bundles/compiler.umd.js:16650:23) at PlatformRef_._bootstrapModuleWithZone (http://localhost:5000/node_modules/@angular/core/bundles/core.umd.js:6707:29) Evaluating http://localhost:5000/ViewContainerRefApp/main.js Error loading http://localhost:5000/ViewContainerRefApp/main.js

I also copied the code from this live sample and I got the same error.

It seems that TemplateRef<any> and ViewContainerRef's metadata are not registerd. But I cannot find out the reason. Anyone can help me? Thank you.

Lcng
  • 706
  • 1
  • 8
  • 17
  • How do you use it? http://plnkr.co/edit/mNS3JuKcLciXcgR0WQQj?p=preview – yurzui Sep 25 '16 at 06:27
  • You need to provide more code, specially your `app.module.ts` – cvsguimaraes Sep 25 '16 at 08:47
  • Here you can see everything is working http://plnkr.co/edit/Indo8JByU7Cpdqb0iOO0?p=info Also, try to put all imports from '@angular/core' in a single statement, it may be some issue with your webpack configuration if you happen to be using it. – cvsguimaraes Sep 25 '16 at 08:48
  • @yurzui Thank you for your help. Now I post all my code. Could you help me again please? – Lcng Oct 18 '16 at 14:34
  • @snolflake Thank you for your help. I have put all imports from '@angular/core' in a single statement. But I get the same error. And..I copy your code to my machine..It throws the same error.. Could you help me again please? – Lcng Oct 18 '16 at 14:49

2 Answers2

1

You have to use one of these options for structural directive:

<div *lcngHw="true"></div>

<template [lcngHw]="true"><div></div></template>

<div template="lcngHw true"></div>

This way you can inject TemplateRef in your component

Plunker Example

This also might be useful:

Community
  • 1
  • 1
yurzui
  • 205,937
  • 32
  • 433
  • 399
  • Have you seen my plunker example? – yurzui Oct 18 '16 at 15:12
  • Could you please add your tsconfig.json? – yurzui Oct 18 '16 at 15:17
  • I'm using Visual Studio 2015. Everything is default. There is no tsconfig.json..I will add one. – Lcng Oct 18 '16 at 15:24
  • https://github.com/Microsoft/TypeScript/issues/3034 http://www.typescriptlang.org/docs/handbook/compiler-options-in-msbuild.html You need to use `--emitDecoratorMetadata` flag – yurzui Oct 18 '16 at 15:34
  • Could you share your project somewhere ? I want to try it with Visual Studio 2015:) – yurzui Oct 18 '16 at 15:35
  • It's solved after I add tsconfig.json with emitDecoratorMetadata set to true. Thank you veeeery much. Do you need my project after is has been solved? – Lcng Oct 18 '16 at 15:39
  • Yes, i will very appreciate :) – yurzui Oct 18 '16 at 15:41
  • I upload my project [here](http://pan.baidu.com/s/1hsG3fy0). It's a popular online disk in the China. Follow this link and click the '下载(8.3M)' button on the page, and then click the '立即下载' button on the modal window, then you can download it..If you cannot visit this link. I will share it on github or visual studio online tomorrow. Thank you for your help. Good night :). – Lcng Oct 18 '16 at 16:00
0

If you are using a tsconfig.json, add emitDecoratorMetaData: true

If you are using Visual Studio without a tsConfig.json add the TypeScriptEmitDecoratorMetadata tag to your project file Note: you will probably need more tags

<PropertyGroup Condition="'$(Configuration)' == 'Debug'">
    <TypeScriptRemoveComments>false</TypeScriptRemoveComments>
    <TypeScriptSourceMap>true</TypeScriptSourceMap>
    <TypeScriptTarget>ES5</TypeScriptTarget>
    <TypeScriptJSXEmit>None</TypeScriptJSXEmit>
    <TypeScriptCompileOnSaveEnabled>True</TypeScriptCompileOnSaveEnabled>
    <TypeScriptNoImplicitAny>False</TypeScriptNoImplicitAny>
    <TypeScriptModuleKind>System</TypeScriptModuleKind>
    <TypeScriptModuleResolution>node</TypeScriptModuleResolution>
    <TypeScriptOutFile />
    <TypeScriptOutDir />
    <TypeScriptGeneratesDeclarations>False</TypeScriptGeneratesDeclarations>
    <TypeScriptNoEmitOnError>True</TypeScriptNoEmitOnError>
    <TypeScriptMapRoot />
    <TypeScriptSourceRoot />
    <TypeScriptExperimentalDecorators>True</TypeScriptExperimentalDecorators>
    <TypeScriptEmitDecoratorMetadata>True</TypeScriptEmitDecoratorMetadata>
</PropertyGroup>