角度重用指令和控制器

时间:2015-09-04 11:29:05

标签: javascript angularjs oop controller singleton

我已经编写了一个自定义下拉选项选择器,一切都很好,它具有获取数据的功能(来自传入的URL)以填充列表。

现在我要做的是重复使用这个组件,但...... 当我将它添加到我的应用程序的另一部分,但使用不同的数据集时,它会复制数据并多次运行控制器函数。

据我所知1有两个问题,服务是单例,所以当我运行函数来填充一些数据时,因为只有一个服务实例,它只是将它添加到当前数据集。

然后另一个问题是控制器确实有实例,所以现在有两个实例,它在每个实例中运行它们。

所以简单的解决方案是复制组件并将其称为不同的名称,这可能会解决问题,如果我想重复使用10次,那么相同组件的10个副本,不是很好

我来自OOP Java背景,所以我可能试图以不支持它的语言使用这些技术;)

所以我知道我必须重新思考如何做到这一点,但是我已经碰到了一点墙,最好如何解决这个问题?

这是(希望)一个JSFiddle,它说明了我运行itno

的内容
var app = angular.module('myApp',[]);

app.directive('mySelector', function () {
return {
 scope: {
      mydata: '='
    },
    restrict: 'EA',
    template:'<select ng-model="timePeriodSelection" ng-options="timePeriodOption.name for timePeriodOption in timePeriodOptions"><option value="">Choose time period</option></select>',
controller: function($scope, myService) {
    //$scope.name = 'Superhero';
    console.log('test',$scope.mydata);
    myService.setData($scope.mydata);
    $scope.timePeriodOptions = myService.getData();
  console.log('test2',myService.getData());
    }
 };
});

app.factory('myService', function() {
var _data=[];    
return {
    setData: function(value){
        for (var a=0;a<value.length;a++){
            _data.push(value[a]);
        }
    },
    getData: function(){
        return _data
    }            
}
});

https://jsfiddle.net/devonCream/ess9d6q6/

我无法出于商业原因向您展示我的代码,但想象一下我传入的内容实际上是一个网址,我有一个获取数据的服务然后将其存储在数组中服务/工厂,每次运行它只是不断添加它们!代码是一个模拟演示。

2 个答案:

答案 0 :(得分:0)

像自定义下拉菜单这样的东西应该是指令而不是别的。也就是说,有很多方法可以实现您尝试使用指令。结帐directive walkthroughs,他们真的很有帮助。

以某种方式,您可能希望拥有隔离范围,使用模板并添加链接功能。

项目始终相同的示例:

Alpha a();
a.value;

将项目传递给每个实例的示例:

angular.module('myApp')
    .directive('myDropdown', function () {
        return {

            scope: {},

            template: '' +
                '<div class="my-dropdown">' +
                    '<div class="my-dropdown-item" ng-repeat="item in items">{{item.text}}</div>' +
                '</div>',

            link: function (scope, element, attrs) {
                scope.items = ['Item 1', 'Item 2', 'Item 3'];
            }

        };
    });

<强> - UPDATE -

您在服务中获取数据的示例:

angular.module('myApp')
    .directive('myDropdown', function () {
        return {

            scope: {
                items: '='
            },

            template: '' +
                '<div class="my-dropdown">' +
                    '<div class="my-dropdown-item" ng-repeat="item in items">{{item.text}}</div>' +
                '</div>'

        };
    });

答案 1 :(得分:0)

因此,除非有人能以不同的方式告诉我,否则我可以看到解决问题的唯一方法是将数据保存在控制器中,从而将数据隔离到自己的控制器实例。将数据保存在其他地方只会导致实例问题。

我已经重构了我的小提琴&#39;显示2个不同的数据源(在本例中我将2个工厂用作模型),将数据带回控制器进行处理然后存储。

通常情况下,如果我没有重复使用该组件,我会将此逻辑放入工厂,但这样做会给我带来我必须开始的问题。

同样在我的真实&#39;项目我检查变量以查看&#39;什么&#39;实例&#39;已被触发并从中调用方法,所有看起来都有点笨拙,但似乎唯一可靠的方法我可以让它工作,也许Angular 2将解决这些问题。

Anyway my link to my jsfiddle

    var app = angular.module('myApp',[]);

app.directive('mySelector', function () {
return { 
    scope: true,
    bindToController:  {
        mydata: '@mydata',     
        timePeriodOptions: '='
    },
    controllerAs: 'selCtrl',
    restrict: 'EA',
    template:'<select ng-model="timePeriodSelection" ng-options="timePeriodOption.name for timePeriodOption in selCtrl.timePeriodOptions"><option value="">Choose time period</option></select>',
    controller: 'selCtrl'
 };
});    
app.controller('selCtrl', function($scope, myService) {
    var selCtrl = this;    
    selCtrl.timePeriodOptions = [];
    if (angular.isString(selCtrl.mydata)){
        processData();
    }
    function processData(){
        var value = myService.getData(selCtrl.mydata);
        for (var a=0;a<value.length;a++){
            selCtrl.timePeriodOptions.push(value[a]);
        }
    };
});

app.factory('myService', function(dataModel1,dataModel2) {
return {
    getData: function(model){
        var _data = []        
        if (model === "1"){
            _data = dataModel1.getData();
        }else{
            _data = dataModel2.getData();
        }
        console.log('data ',_data);
        return _data
    }            
    }
});
app.factory('dataModel1', function() {
    var _data=[{"name":1,"value":1},{"name":2,"value":2},{"name":3,"value":3}];    
    return {
        getData: function(){
            return _data
        }            
    }
});
app.factory('dataModel2', function() {
    var _data=[{"name":4,"value":4},{"name":5,"value":5},{"name":6,"value":6}];    
    return {
        getData: function(){
            return _data
        }            
    }
});