AngularJS ng-include范围

时间:2014-07-30 10:52:49

标签: javascript angularjs angularjs-ng-repeat angularjs-ng-include

我作为开发人员经验丰富,但却是angularjs的初学者,我暂时没有使用过javascript。

我的网站被分成几个angularjs应用程序。但是两个应用程序可能必须显示相同的"实体"类型。

例如,我的第一个应用程序专用于书籍,并将从api(例如:http://example.com/Books)接收以下json数据:

[
    { "id":"1", "title":"...", "publisher":"..." },
    { "id":"2", "title":"...", "publisher":"..." },
]

第二个应用程序更通用,将从api(例如:http://example.com/Things)接收以下json数据:

{
    "count":"3",
    "items":
        // my two books
        { "type":"book", "data":{ "id":"1", "title":"...", "publisher":"..." } },
        { "type":"book", "data":{ "id":"2", "title":"...", "publisher":"..." } },
        // and other things
        { "type":"movie", "data":{ "id":"45", "title":"...", "producer":"..." } },
    ]
}

我创建了一个模板" book.html" :

<div>{{book.title}} ({{book.publisher}})</div>

我在视图中使用它:

<ul><li ng-repeat="book in books" ng-include="'book.html'"/></ul>

到目前为止一直很好......

我现在想使用相同的模板 - 不重复它 - 在第一种情况下显示书籍,在第二种情况下显示书籍:

<ul><li ng-repeat="item in items" ng-include="item.type+'.html'"/></ul>

我的问题不是动态模板。我的问题是:在我的book.html模板中,我使用&#34; book.title&#34;,但对于我的第二个应用,我需要使用&#34; item.data.title&#34;。

在我看来,理想就是:

<ul><li ng-repeat="item in items" ng-include="item.type+'.html'" ng-something="book=item.data"/></ul>

我可以通过&#34;转换&#34;来解决它。我的书籍阵列成第二种格式。但我认为我误解了一些东西,也许我正在以错误的方式使用angularjs。

你可以给我一些线索吗?

由于

3 个答案:

答案 0 :(得分:3)

使用指令。它们起初看起来很吓人,但对于这样的用例它们非常简单:

app.directive("book", function() {
    return {
        restrict: "A",
        templateUrl: "book.html",
        scope: {
            book: "="
        }
}); // isnt' it simple?

第一种情况:

<ul>
    <li ng-repeat="book in books">
        <span book="book"></span>
    </li>
</ul>

第二种情况:

<ul>
    <li ng-repeat="item in items" ng-switch="item.type">
        <span ng-switch-when="book" book="item.data"></span>
        <span ng-switch-when="movie" movie="item.data"></span>
        ...
    </li>
</ul>

答案 1 :(得分:0)

Angular有一个名为ng-init的内置指令,可用于计算作用域上的表达式,这意味着它可用于设置作用域变量,而无需创建控制器或自定义指令。

在这种情况下

    <li ng-repeat="item in items" 
        ng-include="item.type+'.html'" 
        ng-init="book=item.data"/>

应该可以解决这个问题,尽管文档指出它不适用于这个用例:

  

ngInit的唯一合适用途是   别名ngRepeat [$ index,$ even etc]的特殊属性,如下面的演示所示。   除了这种情况,你应该使用控制器而不是ngInit   初始化范围上的值

https://docs.angularjs.org/api/ng/directive/ngInit

答案 2 :(得分:0)

如果您不想更改模板的结构,则需要更改数据结构。创建一个控制器:

app.controller('BookOrMovieController', function($scope) {
    if ($scope.item.type == 'Book') {
        $scope.book = $scope.item.data;
    }
    if ($scope.item.type == 'Movie') {
        $scope.movie = $scope.item.data;
    }
});

然后在包含的模板元素上实例化控制器:

<ul><li ng-repeat="item in items" ng-include="item.type+'.html'" ng-controller="BookOrMovieController"/></ul>