自定义映射Angular片段的范围

时间:2015-01-22 09:49:10

标签: angularjs angularjs-scope

我的思绪仍然在WPF世界中,我正在进入Angular.JS,它揭示了几个类比。但是,我无法弄清楚如何(尽可能)“重新映射”片段的范围,以便更好地重用模板。

考虑这个例子:

  <html ng-app="myApp">
  <body>
    <div id="container" ng-controller="ContentCtrl">
        <div ng-repeat="item in content">
            <a href='#' ng-click="select(item)">{{item.title}}</a>
        </div>
        <hr>

        <!-- here is the target fragment -->
        <div ng-whatever="??? func(selected)">
            <h1>{{title}}</h1>
            <div ng-include="mapper($scope)"></div>
        </div>

   </div>

    <script type="text/ng-template" id="entry-photo">
        <div>
            <span><a href="{{data}}"><img ng-src="{{data}}"></a></span>
        </div>
    </script>

    <script type="text/ng-template" id="entry-video">
        <div>
            <iframe ng-src="{{data}}" width="280" height="200" frameborder="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe>
        </div>
    </script>

    <script type="text/ng-template" id="entry-notes">
        <div>{{data}}</div>
    </script>
  </body>
  </html>

和相关脚本:

var app = angular.module('myApp', []);

function ContentCtrl($scope) {
    $scope.selected = null;
    $scope.content = [
        {"content_type" : "image", "title" : "Image 00", "data" : "http://www.letsgodigital.org/html/review/panasonic/lumix-dmc-fx33/photography/panasonic-fx33_small8.jpg"},
        {"content_type" : "video", "title" : "Video 00", "data" : "http://player.vimeo.com/video/37176398"},
        {"content_type" : "notes", "title" : "Notes 00", "data" : "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc pulvinar pretium felis. Vivamus nibh felis, condimentum sit amet laoreet luctus, posuere auctor lorem. Nullam malesuada."}
    ];

    $scope.select = function(e){
        $scope.selected = e;
    };

    $scope.mapper = function(e){
        switch(e.content_type){
            case "image": return "entry-photo";
            case "video": return "entry-video";
            case "notes": return "entry-notes";
        }
    };
}

当然上面的标记是 NOT 正在工作,显然是因为它被描述为伪代码:

        <div ng-whatever="??? func(selected)">
            <h1>{{title}}</h1>
            <div ng-include="mapper($scope)"></div>
        </div>

我想创建一个“自定义范围”(从原始范围派生),以便任何降序节点都将继承重新映射的值。在此示例中,函数可以只是“selected”属性的值。

有没有简单的方法来实现它?

让我说我更感兴趣的是学习,而不是任何完全不同的解决方法。因为在WPF中类似的情况很常见但很难解决,我想知道如何在Angular中做。

3 个答案:

答案 0 :(得分:0)

如果我清楚地了解,你想要什么,你可以宣布另一个控制器,它将创建新的范围。 从子范围,您可以使用$scope.$parent对象从父范围获取值。

有关AngularJS范围的更多详细信息,请参见https://docs.angularjs.org/guide/scope

这是我的简单例子。

<div ng-controller="ParentCtrl">
    {{name}}
    <div ng-controller="NestedCtrl">
        {{title}}
        <br/>
        {{$parent.name}}
    </div>
</div>

function ParentCtrl($scope) {
    $scope.name = 'Parent';
}

function NestedCtrl($scope) {
    $scope.title = 'Nested';
}

这是 JSFiddle

答案 1 :(得分:0)

首先,您的代码

$scope.mapper = function(e){
    switch(e.content_type){
        case "image": return "entry-photo";
        case "video": return "entry-video";
        case "notes": return "entry-notes";
    }
};

期望e将是一个项目,而不是你传递的$ scope

ng-include="mapper($scope)"

所以

ng-include="mapper()"

$scope.mapper = function(){
    if($scope.selected !== null) {
        switch($scope.selected.content_type){
            case "image": return "entry-photo";
            case "video": return "entry-video";
            case "notes": return "entry-notes";
        }
    } else {
        return "blank-tpl";
    }
};

关于范围,您的指令将在控制器范围内工作,因此您可以在模板中使用选定的变量,如下所示:

<script type="text/ng-template" id="entry-notes">
    <div>{{selected.data}}</div>
</script>

就是这样。

当然,如果你不想使用你的控制器范围,你可以用包含父范围或隔离范围的自己的范围编写指令,在文档中更多。

答案 2 :(得分:0)

我相信这是你要求的: http://www.bennadel.com/blog/2441-nested-views-routing-and-deep-linking-with-angularjs.htm

您还可以使用指令: http://onehungrymind.com/angularjs-dynamic-templates/

您还可以通过定义工厂(通常称为服务)在控制器之间共享数据。多个控制器是可选的: https://egghead.io/lessons/angularjs-sharing-data-between-controllers

指令模板可以包含(见下文)或html字符串(作为第二个链接): http://www.portlandwebworks.com/blog/testing-angularjs-directives-handling-external-templates