我正在使用Angular js指令并绑定数据以在视图中显示。我有条件的看法。我使用相同的视图来读取数据以及编辑数据。我管理一个标志edit = true并在标志“编辑”上使用ng-switch我改变视图。
大部分时间都运作良好;但是我意识到,即使场景背后的数据得到更新,一些视图也不会更新。我基本上做了什么;在编辑模式下单击“确定”按钮;使用ng-click我改变了flag edit = undefined,因为数据变了,所以我的假设是它会改变视图。它肯定在大多数时间工作,但突然停止工作。我通过打印数据检查了控制台,我看到ng-click实际上是正确更新标志。以下摘录代码。
查看代码* [已更新] *:
<!--In case of edit render it as text box-->
<ng:switch on="file.edit">
<div ng:switch-when="true">
<input type="text" ng-model="file.name" class="file-label" value="{{file.name}}" />
<i class="icon-ok" ng-click="addFile({{$index}})"></i>
<i class="icon-remove" ng-click="cancelAddFile({{$index}})"></i>
</div>
<div ng:switch-when="undefined">
<!--if it is not edit case then render as label-->
<!--Add file name as a label-->
<span class="file-label" >{{file.name}}</span>
</div>
</ng:switch>
以下是指令代码* [更新] *。
的摘录//project directive as element for project contents
app.directive("projectcontents", ['Contents', function (projectContents) {
return {
restrict: "E",
templateUrl: "/xopus/view/projectstructure/ProjectContents.html",
replace: true,
scope: {
project: '='
},
link: function (scope, element, attrs) {
/*Edit file in project*/
scope.editFile = function (fileIndex) {
//print log for debug purpose
console.log("Edit file at index " + fileIndex);
//make service call
//update edit flag
scope.files[fileIndex].edit = true;
};
/*Remove file in project*/
scope.deleteFile = function (fileIndex) {
//make service call
//print log for debug purpose
console.log("Remove file at index " + fileIndex);
//Remove this file entry form data model
scope.files.splice(fileIndex, 1);
};
/*Add file in project*/
scope.addFile = function (fileIndex) {
//print log for debug purpose
console.log("Add file at index " + fileIndex);
//make service call
//update data binding to update edit=false
//update edit flag
scope.files[fileIndex].edit = undefined;
};
/*Cancel add file */
scope.cancelAddFile = function (fileIndex) {
//print log for debug purpose
console.log("Cancel file at index " + fileIndex);
//Remove this file entry form data model
scope.files.splice(fileIndex, 1);
};
}
};
} ]);
我还在学习Angular,我肯定会做一些基本的错误。请帮忙。
答案 0 :(得分:1)
为什么视图无法正确更新
以下是控制器的范围最初的样子:
//Parent scope
$scope = {
...
files: [..]
...
}
现在,当您添加ng-switch
指令时,此指令会创建一个新范围。此范围继承父范围的所有属性:
//Child scope
$scope = {
...
files: [...]
...
}
请注意,它也具有files
属性/模型 - 这绑定到父作用域的files
属性。但是,这是一种单向绑定 - 对父级的更新将反映在子级中,但子级的更新不会反映在父级中。
现在,当单击发生并且您希望从编辑模式切换到显示模式时,会发生的情况是您正在更改子作用域的files
属性而不是父作用域 - 父作用域上的文件范围仍处于“编辑”模式 - ng-switch
指令仍引用父作用域上的file
属性,因此切换不会发生。
如何解决此问题
当我请求您删除不必要的代码时,这只是为了易读性和更容易理解,这不是解决方案。您已经更好地更新了代码,这导致了问题的原因。但是,仍有一些失败的结局。例如,您如何定义范围的files
模型?它似乎没有在指令中定义 - 只是修改过。你能提供这些信息吗?
与此同时,如果我对问题的分析是正确的,那么将scope.files
函数中addFile
的出现替换为scope.$parent.files
- 我认为应该这样做 - 它应该更新父控制器范围内的文件状态,因此应该由ng-switch
指令选取,从而正确地更新您的视图。
答案 1 :(得分:1)
我通过使用“fileId”而不是Angular生成的“$ index”修复了这个问题。似乎callmekatootie解释的范围逻辑导致一些问题更新$ index。我不确定我需要更改到哪里来修复$ index问题因此我改变了我的逻辑以使用fileId(而不是$ index),现在它工作正常。以下是修改后的addFile()
/*Add file in project*/
scope.addFile = function (fileId) {
//find out index of given file ID
var fileIndex = scope.getFileIndex(fileId);
//update data binding to update edit=false
scope.files[fileIndex].edit = undefined;
};
/*Get Index of file in files object */
scope.getFileIndex = function (fileId) {
//print log for debug purpose
console.log("Get file index for fileId " + fileId);
//find out index of given file ID
var fileIndex = undefined;
for (var i = 0; i < scope.files.length; i++) {
if (scope.files[i]._id === fileId) {
fileIndex = i;
break;
}
}
return fileIndex;
};
不确定这是不是很完美。