我有一个指令,它接收一个集合并构建一个下拉列表。
.directive("lookupdropdown", function () {
return {
restrict: 'E',
scope: {
collectionset: '=',
collectionchoice: '='
},
replace: true,
template: '<select class="input-large" ui-select2 ng-model="collectionchoice" data-placeholder="">' +
' <option ng-repeat="collection in repeatedCollection" value="{{collection.id}}">{{collection.description}}</option>' +
'</select>',
controller: ["$scope", function ($scope) {
$scope.repeatedCollection = new Array(); //declare our ng-repeat for the template
$scope.$watch('collectionset', function () {
if ($scope.collectionset.length > 0) {
angular.forEach($scope.collectionset, function (value, key) { //need to 'copy' these objects to our repeated collection array so we can template it out
$scope.repeatedCollection.push({ id: value[Object.keys(value)[0]], description: value[Object.keys(value)[1]] });
});
}
});
$scope.$watch('collectionchoice', function (newValue, oldValue) {
debugger;
$scope.collectionchoice;
});
} ]
}
});
这很好用。它建立了下拉没有问题。当我更改下拉值时,第二个监视函数被调用,我可以看到它将集合选择的值设置为我想要的值。但是,我在指令中添加的集合选择不会绑定到新选项。
<lookupDropdown collectionset="SecurityLevels" collectionchoice="AddedSecurityLevel"></lookupDropdown>
这是HTML标记。
这是javascript:
$scope.SecurityLevels = new Array();
$scope.GetSecurityLevelData = function () {
genericResource.setupResource('/SecurityLevel/:action/:id', { action: "@action", id: "@id" });
genericResource.getResourecsList({ action: "GetAllSecurityLevels" }).then(function (data) {
$scope.AddedSecurityLevel = data[0].SCRTY_LVL_CD;
$scope.SecurityLevels = data;
//have to get security levels first, then we can manipulate the rest of the page
genericResource.setupResource('/UserRole/:action/:id', { action: "@action", id: "@id" });
$scope.GetUserRoles(1, "");
});
}
$scope.GetSecurityLevelData();
然后当我发布我的新用户角色时,我设置了这样的用户角色字段:
NewUserRole.SCRTY_LVL_CD = $scope.AddedSecurityLevel;
但这仍然是第一项,即使我更新了下拉列表,根据监视功能,它已更改为正确的值。我在这里缺少什么?
答案 0 :(得分:1)
由于Javascript中的原型性继承,您遇到了这个问题。让我试着解释一下。一切都是Javascript中的一个对象,一旦你创建了一个对象,它就会继承所有的Object.Prototype,最终会导致最终的对象,即Object。这就是为什么我们能够.toString()javascript(甚至是函数)中的每个对象,因为它们都是从Object继承的。
关于指令的这个特殊问题是由于对Angular JS中的$ scope的误解造成的。 $ scope不是模型,但它是模型的容器。请参阅下文,了解在$ scope上定义模型的正确和错误方法:
...
$scope.Username = "khan@gmail.com"; //Incorrect approach
$scope.Password = "thisisapassword";//Incorrect approach
...
$scope.Credentials = {
Username: "khan@gmail.com", //Correct approach
Password: "thisisapassword" //Correct approach
}
...
这两个声明有很大的不同。当您的指令更新其范围(指令的隔离范围)时,它实际上完全用新值覆盖了引用,而不是更新对父作用域的实际引用,因此它断开了指令和控制器的范围。
您的方法如下:
<lookupDropdown collectionset="SecurityLevels" collectionchoice="$parent.AddedSecurityLevel"></lookupDropdown>
这种方法的问题在于虽然它有效,但它不是推荐的解决方案,这就是原因。如果你的指令被置于另一个指令中,并且在指令范围和实际控制器之间有另一个隔离范围,那么你将不得不做$parent.$parent.AddedSecurityLevel
,这可能会永远持续下去。因此,不是推荐的解决方案。
<强>结论:强>
始终确保有一个对象在范围内定义模型,无论何时使用隔离范围或使用使用隔离范围的ng指令,即ng-model
,只需查看是否有点(。某个地方,如果它丢失了,你可能做错了。
答案 1 :(得分:0)
这里的问题是我的指令被转换为另一个指令。让范围im传递给它所在的指令的子节点。所以类似于$ parent - &gt; $ child - &gt; $孩子。这当然是对第三层和第二层进行了更改。但第一层不知道发生了什么。这修好了它:
<lookupDropdown collectionset="SecurityLevels" collectionchoice="$parent.AddedSecurityLevel"></lookupDropdown>