angularjs - 通过服务在控制器之间共享数据

时间:2015-05-14 00:03:27

标签: angularjs

我有一个2控制器[FirstController,SecondController]通过名为filecomm的服务共享两个数据数组(myFileList,dummyList)。 有一个属性指令filesread与隔离范围绑定到文件输入,以便从中获取文件数组。 我的问题是,当我选择带有输入的文件时,我的服务中的myFileList数组永远不会更新。但是,dummyList数组会立即在第二个div(inner2)中更新。有人知道为什么会这样吗? 出于某种原因,当我从第二个ngrepeat(从secondCtrl.dummyList中的fi)切换到(在secondCtrl.myFileList中的fi)时,它停止工作。 任何帮助将不胜感激。

标记

<div ng-app="myApp" id="outer">
<div id="inner1" ng-controller="FirstController as firstCtrl">
<input type="file" id="txtFile" name="txtFile" 
maxlength="5" multiple accept=".csv" 
filesread="firstCtrl.myFileList"
update-data="firstCtrl.updateData(firstCtrl.myFileList)"/>
    <div>
        <ul>
            <li ng-repeat="item in firstCtrl.myFileList">
                <fileuploadrow my-file="item"></fileuploadrow>
            </li>
       </ul>
    </div>
    <button  id="btnUpload" ng-click="firstCtrl.uploadFiles()"
     ng-disabled="firstCtrl.disableUpload()">Upload
     </button>     
</div>
    <div id="inner2" ng-controller="SecondController as secondCtrl">
        <ul ng-repeat="fi in secondCtrl.dummyList">
            <li>Hello</li>
        </ul>    
    </div>    
</div>

JS

angular.module('myApp', [])
.controller('FirstController',
['$scope','filecomm',function ($scope,filecomm) {
    this.myFileList = filecomm.myFileList; 

    this.disableUpload = function () {
    if (this.myFileList) {
        return (this.myFileList.length === 0);
    }
    return false;
};

    this.uploadFiles = function () {
        var numFiles = this.myFileList.length;
        var numDummies = this.dummyList.length;
        filecomm.addDummy('dummy no' + numDummies + 1);
        console.log('Files uploaded when clicked:' + numFiles);
        console.log('dummy is now:'+ this.dummyList.length);
        };

    this.updateData = function(newData){
        filecomm.updateData(newData);
        console.log('updated data first controller:' + newData.length);
    };

    this.dummyList = filecomm.dummyList;

    console.log('length at init:' + this.myFileList.length);
}]) //FirstController

.controller('SecondController', 
 ['$scope', 'filecomm', function($scope,filecomm) {
    var self = this;
    self.myFileList = filecomm.myFileList;

    self.dummyList = filecomm.dummyList;

    console.log('SecondController myFileList - length at init:' +
    self.myFileList.length);
    console.log('ProgressDialogController dummyList - length at init:' + 
    self.dummyList.length);
}])  //Second Controller

.directive('filesread',[function () {
    return {
        restrict: 'A',
        scope: {
            filesread: '=',
            updateData: '&'
        },
        link: function (scope, elm, attrs) {

            scope.$watch('filesread',function(newVal, oldVal){
                console.log('filesread changed to length:' +  
                             scope.filesread.length);

        });

            scope.dataFileChangedFunc = function(){
                scope.updateData();
                console.log('calling data update from directive:' +   
                scope.filesread.length);
            };

            elm.bind('change', function (evt) {


                scope.$apply(function () {

                    scope.filesread = evt.target.files;

                    console.log(scope.filesread.length);
                    console.log(scope.filesread); 


                });

                scope.dataFileChangedFunc();

            });



        }
    }
}])    //filesread directive

.directive('fileuploadrow', function () {
    return {
        restrict: 'E',
        scope: {
            myFile: '='
        },
        template: '{{myFile.name}} - {{myFile.size}} bytes'
    };

})  //fileuploadrow directive

.service('filecomm', function FileComm() {
    var self = this;;

    self.myFileList = [];

    self.dummyList = ["item1", "item2"];

    self.updateData = function(newData){
    self.myFileList=  newData;
    console.log('Service updating data:' + self.myFileList.length);
    };

    self.addDummy = function(newDummy){
    self.dummyList.push(newDummy);
    };

});  //filecomm service

请参阅以下内容 JSFiddle 如何测试:

选择1个或多个.csv文件,并查看下面列出的每个文件。 对于选择的每个文件,第二个div中的ngrepeat应显示Hello。事实并非如此。 将第二个div中的ngrepat更改为secondCtrl.dummyList 选择文件并开始单击上载后,您将看到每次单击都会向ul添加新的列表项。 为什么dummyList会更新而myFileList不会更新?

1 个答案:

答案 0 :(得分:1)

你有几个问题。

首先,在filecomm服务updateData函数中,您正在替换列表而不是更新它。

其次,更改并未立即更新视图,我通过添加$ rootScope来解决此问题。$ apply强制视图更新。

更新了JSFiddle,请告诉我这是不是您要找的https://jsfiddle.net/bdeczqc3/76/

Global Group     Option ID
floor                1
hardwood             1
parkay               1
handle               0
brass                1
stainless            1
nickel               1
door                 0
hardwood             1
steel                1
screen               1

或者,您可以在FirstController中的updateData函数中执行$ scope。$ apply,而不是在$ fileSm服务中执行$ root.Scope。

Alternate JSFiddle:https://jsfiddle.net/bdeczqc3/77/

.service('filecomm', ["$rootScope" ,function FileComm($rootScope) {
    var self = this;
    self.myFileList = [];

    self.updateData = function(newData){
        $rootScope.$apply(function(){
            self.myFileList.length = 0;
            self.myFileList.push.apply(self.myFileList, newData);
            console.log('Service updating data:' + self.myFileList.length);
        });        
    };    

}]);  //filecomm service