简体   繁体   English

AngularJS ng-include范围

[英]AngularJS ng-include scope

I am experienced as a developer but a beginner in angularjs and I have not used javascript for a while. 我作为开发人员经验丰富,但在angularjs的初学者,我还没有使用javascript一段时间。

My site is separated into several angularjs apps. 我的网站被分成几个angularjs应用程序。 But two apps could have to display the same "entity" types. 但是两个应用程序可能必须显示相同的“实体”类型。

For example my first app is dedicated to books and would receive from an api (for example: http://example.com/Books ) the following json data: 例如,我的第一个应用程序专用于书籍,并将从api(例如: http//example.com/Books )接收以下json数据:

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

The second app is more general and would receive from an api (for example: http://example.com/Things ) the following json data: 第二个应用程序更通用,将从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":"..." } },
    ]
}

I created a template "book.html" : 我创建了一个模板“book.html”:

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

I use it in my view with : 我在以下视图中使用它:

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

So far so good... 到现在为止还挺好...

I now would like to use the same template - without duplicating it - to display the books in the first case and in the second with something like : 我现在想使用相同的模板 - 不重复它 - 在第一种情况下显示书籍,在第二种情况下显示书籍:

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

My issue is not dynamic templates. 我的问题不是动态模板。 My issue is: in my book.html template, I use "book.title", but for my second app, I would need to use "item.data.title". 我的问题是:在我的book.html模板中,我使用“book.title”,但对于我的第二个应用程序,我需要使用“item.data.title”。

The ideal, in my mind, would have been something like : 在我看来,理想的是:

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

I could resolve it by "converting" my books array into the second format. 我可以通过将我的书籍数组“转换”成第二种格式来解决它。 But I think I misunderstood something and perhaps I am using angularjs in a wrong way. 但我认为我误解了一些东西,也许我正在以错误的方式使用angularjs。

Could you please give me some clues ? 你能告诉我一些线索吗?

Thanks 谢谢

Use directives. 使用指令。 They look intimidating at first, but they are quite simple for such use cases: 它们起初看起来很吓人,但对于这种用例它们非常简单:

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

First case: 第一种情况:

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

Second case: 第二种情况:

<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 has a built-in directive called ng-init that can be used to evaluate expressions on a scope, meaning it can be used to set scope-variables without having to create a controller or a custom directive. Angular有一个名为ng-init的内置指令,可用于计算作用域上的表达式,这意味着它可用于设置作用域变量,而无需创建控制器或自定义指令。

In this case 在这种情况下

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

Should do the trick, although the documentation specifies that it is not intended for this use-case: 应该这样做,虽然文档指定它不适用于此用例:

The only appropriate use of ngInit is for aliasing special properties of ngRepeat [$index, $even etc], as seen in the demo below. ngInit的唯一合适用途是用于别名ngRepeat [$ index,$ even etc]的特殊属性,如下面的演示所示。 Besides this case, you should use controllers rather than ngInit to initialize values on a scope . 除了这种情况, 您应该使用控制器而不是ngInit来初始化作用域上的值

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

If you don't want to change the structure of your templates, you will need to change the structure of your data. 如果您不想更改模板的结构,则需要更改数据的结构。 Create a controller: 创建一个控制器:

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;
    }
});

Then instantiate the controller on the included template element: 然后在包含的模板元素上实例化控制器:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM