我的思绪仍然在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中做。
答案 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