【问题标题】:Angular2 (Typescript) directive not showing information passed to itAngular2(Typescript)指令未显示传递给它的信息
【发布时间】:2016-10-15 00:23:06
【问题描述】:

我目前正在尝试将类别结构合并到我正在构建的应用程序的菜单中。我有一个从 API 框中调用类别的服务,这一切正常,在实现这个新功能之前,我已经返回并正确显示了结果。目前没有显示任何内容,控制台中也没有错误。

这是我的 app.component.ts

import { Component, OnInit }       from 'angular2/core';
import { RouteConfig, ROUTER_DIRECTIVES, ROUTER_PROVIDERS } from 'angular2/router';
import { ProductComponent } from './components/product.component'

// Services
import { ProductService }  from './services/product.service';
import { CategoryService } from './services/category.service';

// Classes
import { Product } from './classes/Product';
import { Category } from './classes/Category';
import {serializeXmb} from "angular2/i18n";

// Directives
import { CategoryTree } from './directives/category-tree';

@Component({
    selector: 'product-display',

    templateUrl:'./app/views/category-view.html',

    directives: [
        ROUTER_DIRECTIVES,
        ProductComponent,
        CategoryTree
    ],
    providers: [
        ROUTER_PROVIDERS,
        ProductService,
        CategoryService
    ]
})

@RouteConfig([
    {
        path : '/dashboard',
        name : 'Product',
        component : ProductComponent,
        useAsDefault : true
    }
])

export class AppComponent {
    constructor(private _productService: ProductService, private _categoryService: CategoryService) {}

    title = 'Product Viewer';
    contentLoaded = false;
    categories = [];
    selectedCategory = null;
    selectedProduct = Product;
    products = [];
    APIError = [];

    getProducts() {
        this._productService.getProducts()
            .subscribe(
                products => {this.products = products},
                error    => {this.APIError = error},
                ()       => this.contentLoaded = true
            );
    }
    getCategories() {
        this._categoryService.getCategories({
            order           : 'asc',
            order_by        : 'name',
            sub_cats        : true,
            group_by_parent : true
        })
            .subscribe(
                categories => {this.categories = categories},
                error      => {this.APIError = error},
                ()         => this.contentLoaded = true
            );
    }
    selectCategory(category: Category) {
        this.selectedCategory = category
    }
    ngOnInit() {
        this.getProducts();
        this.getCategories();
    }
}

如您所见,我正在调用 CategoryService 服务中的一个函数,该函数返回我想在页面上显示的所有类别。由于这是一个 aSync 调用,我使用 getCategories 函数在 Observer 返回时订阅它。

这里是组件调用的category-view-html,用来展示组件:

<div id='left-menu-wrapper'>
    <div id='left-menu'>
        <h1>{{title}}</h1>
        <h2>Categories</h2>
        <category-tree [categories]="categories"></category-tree>
        <div *ngIf="selectedCategory">
            {{selectedCategory.name}}
        </div>
    </div>
    <div *ngIf="!contentLoaded" class='spinner'></div>
</div>
<product-view [product]="selectedProduct"></product-view>

在这里你可以看到我试图调用'category-tree'的指令。我还将它包含在名为 CategoryTree 的 app.component.ts 指令属性中。我使用 [categories]="categories" 行传递从服务返回的类别。

这是我要导入 app.component.ts 的 CategoryTree 指令:

import { Component, Input } from 'angular2/core';

@Component({
    selector: 'category-tree',
    templateUrl: './app/views/category-tree.html',
    directives: [CategoryTree]
})

export class CategoryTree {
    @Input categories;
}

如您所见,我定义了选择器并包含了要使用的模板。然后我导出指令并指示类别属性成为来自 app.component.ts 的接受输入。这是模板(尚未完成)。

<ul class="categories">
    <li *ngFor="#category of categories">
        <span (click)="selectCategory(category)" [class.selected]="category === selectedCategory">{{category.name}}</span>
        <ul *ngIf="category.sub_categories.length" class='sub-category' data-cat="category.id">
            <li *ngFor="#sub_category of category.sub_categories">
                <span (click)="selectCategory(sub_category)" [class.selected]="sub_category === selectedCategory">{{sub_category.name}}</span>
            </li>
        </ul>
    </li>
</ul>

由于某种原因,类别似乎没有显示,并且控制台中没有错误让我相信这可能是因为在从服务返回类别之前包含了指令?我认为这不会是一个问题,因为该指令订阅了 Observable 并且会在 Observable 更改时相应地更新自己?

谁能看到我在这里可能出错的地方?

谢谢

【问题讨论】:

    标签: typescript angular


    【解决方案1】:

    更新

    随着@NgModule 的引入以及directives 到@NgModule 的迁移,forwardRef 应该不再需要了。

    原创

    从@Component() 装饰器看来,您在Category 树中使用了CategoryTree,但不清楚该组件的模板是什么。

    如果要以这种递归方式使用组件,需要使用forwardRef

    import {forwardRef} from 'angular2/core'; 
    // or @angular/core in newer Angular versions
    

    并像这样使用它:

    directives: [forwardRef(() => CategoryTree)]
    

    【讨论】:

    • 嗨。是的,我忘了补充一点,这将是一个递归组件。我将代码修改为您建议的内容,但仍然看不到应该传递给它的类别。
    • 你检查CategoryTree 组件被实例化了吗?我会添加一个constructor() { console.log('CategoryTree'); } 来检查。还有一个ngOnChanges() { console.log('categories changed', this.categories);}。请在您的问题中添加这将打印到控制台的内容。
    • 允许复制的 Plunker 会很有帮助。有关类似示例,另请参阅 stackoverflow.com/questions/37746516/use-component-in-itself/…。
    【解决方案2】:

    我解决了。这只是类别树中@Input 中缺少的一对括号:

    export class CategoryTree {
        @Input categories;
        constructor() {
            console.log("i am category tree");
        }
    }
    

    应该是这样的

    我解决了。这只是类别树中@Input 中缺少的一对括号:

    export class CategoryTree {
        @Input categories;
        constructor() {
            console.log("i am category tree");
        }
    }
    

    应该是:

      export class CategoryTree {
                @Input() categories;
                constructor() {
                    console.log("i am category tree");
                }
            }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-23
      • 2016-12-22
      • 2016-05-23
      • 2019-08-31
      • 1970-01-01
      • 2017-06-10
      相关资源
      最近更新 更多