Javascript 角度包括范围

Javascript 角度包括范围,javascript,angularjs,angularjs-ng-repeat,angularjs-ng-include,Javascript,Angularjs,Angularjs Ng Repeat,Angularjs Ng Include,作为一名开发人员,我很有经验,但我是angularjs的初学者,我有一段时间没有使用javascript了 我的网站被分成几个angularjs应用程序。但两个应用程序可能必须显示相同的“实体”类型 例如,我的第一个应用程序专用于书籍,并将从api(例如:)接收以下json数据: [ { "id":"1", "title":"...", "publisher":"..." }, { "id":"2", "title":"...", "publisher":"..." }, ]

作为一名开发人员,我很有经验,但我是angularjs的初学者,我有一段时间没有使用javascript了

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

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

[
    { "id":"1", "title":"...", "publisher":"..." },
    { "id":"2", "title":"...", "publisher":"..." },
]
{
    "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":"..." } },
    ]
}
第二个应用程序更通用,将从api(例如:)接收以下json数据:

[
    { "id":"1", "title":"...", "publisher":"..." },
    { "id":"2", "title":"...", "publisher":"..." },
]
{
    "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”:

{{book.title}}({{book.publisher})
在我看来,我将其用于:

<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>
<ul><li ng-repeat="item in items" ng-include="item.type+'.html'" ng-something="book=item.data"/></ul>
我的问题不是动态模板。我的问题是:在我的book.html模板中,我使用“book.title”,但对于我的第二个应用程序,我需要使用“item.data.title”

在我看来,理想是这样的:

<ul><li ng-repeat="item in items" ng-include="item.type+'.html'"/></ul>
<ul><li ng-repeat="item in items" ng-include="item.type+'.html'" ng-something="book=item.data"/></ul>
我可以通过将books数组“转换”为第二种格式来解决这个问题。但我想我误解了一些东西,也许我用错了angularjs

你能给我一些线索吗


感谢使用指令。它们一开始看起来很吓人,但对于这样的用例来说非常简单:

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>
  • ...

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

在这种情况下

    <li ng-repeat="item in items" 
        ng-include="item.type+'.html'" 
        ng-init="book=item.data"/>
  • 应该做到这一点,尽管文档指定它不适用于此用例:

    ngInit的唯一适当用途是 ngRepeat[$index,$偶数等]的特殊属性别名,如下面的演示所示。 除此之外,您应该使用控制器而不是ngInit来 初始化作用域上的值


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

    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>
    
    • ng init
      会起作用吗?完美的非常感谢。实际上,这不是
      nginit
      的目的。所指的“特殊属性”是
      $index
      $even
      等,这些属性在嵌套的
      ng repeat
      指令中被覆盖-因此,您可能需要对它们进行别名。@AlexG在第二次通读时,我第一次阅读时似乎误解了文档。我仍然认为这是可以接受的使用
      ng init
      ,但这是迄今为止解决这个问题最不冗长的方法。我同意它确实适用于这个简单的案例,我很抱歉在我无法费心编写控制器或指令时使用它。谢谢。这是一个很好的替代伊瓦尼的答案。我正在阅读更多关于指令的内容,尽管它们的声明看起来很难理解(或者像你说的那样令人生畏)。@Loic指令可能是复杂的事情,但是你越早开始使用它们,你就越早能够利用它们。