假设我有一个这样的模板:
<div>
<div>
<span>Description:</span><span>{{YPOBatch.YarnPOBatch.YarnType.YarnTypeDesc}}</span>
</div>
<div>
<span>ID:</span><span>{{YPOBatch.YarnPOBatch.YarnType.YarnTypeID}}</span>
</div>
</div>
为了编写更清晰、更易于阅读和维护的代码,我希望能够编写如下内容:
<div ng-directive-that-I-am-at-a-loss-for="YPOBatch.YarnPOBatch.YarnType">
<div>
<span>Description:</span><span>{{YarnTypeDesc}}</span>
</div>
<div>
<span>ID:</span><span>{{YarnTypeID}}</span>
</div>
</div>
这样两个代码块将是等效的。有没有一个开箱即用的角度指令可以做我想做的事?
好吧,从表面上看,这似乎是一个不错的主意......但实际上我不确定这是一个好主意。
方法 1.花哨的指令,这可能是一个坏主意
为此,您需要创建一个新的范围并将其$compile到包含的视图中。换句话说,你获取指令所在的元素的内脏,克隆它,创建一个新的子 Scope,更新它以获得你指定的属性中的值,然后将新的子作用域绑定到克隆的元素,然后将其附加到你的元素。然后,还将原始属性指定为新创建的范围。清澈如泥?嘿。
编辑:我已经消除了双向绑定问题
编辑:。。。并简化了很多
不过,这仍然有点疯狂,因为现在您原来的$scope.property变成了它自己的范围。但它有效。
无论如何,这里有一个关于如何做到这一点的片段,以及一些代码......我不建议使用它,甚至不建议尝试它。
app.directive('notSureWhyYoudWantThis', function($parse) {
return {
scope: true,
link: function(scope, elem, attrs) {
// get the property getter/setter
var property = $parse(attrs.notSureWhyYoudWantThis);
// get the value from the scope (inherited from parent)
var base = property(scope);
// extend the child scope with whatever is in the base property.
angular.extend(scope, base);
// now set the property on the parent scope to be the child scope,
// so it updates both ways.
property.assign(scope.$parent, scope);
}
}
});
<div not-sure-why-youd-want-this="YPOBatch.YarnPOBatch.YarnType">
<div>
<span>Description:</span><span>{{YarnTypeDesc}}</span>
</div>
<div>
<span>ID:</span><span>{{YarnTypeYarnTypeID}}</span>
</div>
</div>
<小时 />方法 2.最佳主意:将您的数据整理成适当的模型,MVC程序员先生!
所以这里最好的想法是最不性感的,你把你从数据源(AJAX,LocalStorage等(获得的丑陋数据,你实际上把它整理成一个最能代表你的视图/显示逻辑的模型。然后,将该模型放在$scope的属性中。然后结束。
这确实是你应该在MVC中做的事情,特别是如果你是Domain Driven,但它对某些人来说没有吸引力,因为会产生额外的工作,有时希望能够以单一的形式直接提交数据。
var ypoBatch= myService.getSomeDataFromSomething();
$scope.yarnType = {
id: ypoBatch.YarnPOBatch.YarnTypeYarnTypeID,
description: ypoBatch.YarnPOBatch.YarnTypeDesc
};
那么在您看来:
<div>
<div>
<span>Description:</span> <span>{{yarnType.description}}</span>
</div>
<div>
<span>ID:</span> <span>{{yarnType.id}}</span>
</div>
</div>
无聊:是的。
更好:可能。
显然,你如何做上述事情将是情境化的。但这就是想法。现在你有很多方法可以剥这只猫的皮。祝你好运。
箱即用,我不相信有这样的事情。你可以尝试这样的事情
app.directive('expandModel', function() {
return {
scope: true,
link: function(scope, elem, attrs) {
angular.extend(scope, scope.$eval(attrs.expandModel));
}
}
});
这将为指令创建一个新作用域,该指令仍原型继承自其父级,同时复制指定属性路径的所有模型值。
或者,如果您希望模型值发生更改,请使用 scope.$watch 而不是 scope.$eval。
普伦克现在正在行动,否则我会给你一个扑通
我认为你正在为错误的抽象级别而射击。 如果需要指令来显示有关纱线的信息,则可以将整个演示文稿包装成可重用的块。
module.directive('yarnDisplay', [function() {
return {
restrict: 'E',
scope: {
yarn: '=' //the parent scope will manage finding the yarn
},
template: '<div><div><span>Description:</span><span>{{yarn.YarnTypeDesc}}</span></div><div><span>ID:</span><span>{{yarn.YarnTypeYarnTypeID}}</span></div></div>',
link: function(scope, el, attrs, controller) {
}
}]);
使用该指令,每当您需要显示有关纱线的信息时,您都会包含以下 HTML:
<yarn-display yarn='YPOBatch.YarnPOBatch' />