Angular js数据绑定不会间歇性地更新视图

时间:2013-08-24 04:17:58

标签: angularjs angularjs-directive angular-ui

我正在使用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,我肯定会做一些基本的错误。请帮忙。

2 个答案:

答案 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;
            };

不确定这是不是很完美。