Angular - 绑定指令值到控制器对象

时间:2016-06-13 19:15:14

标签: arrays angularjs angularjs-directive binding

我试图将一个数组从一个控制器传递给一个指令,并且对于某些(可能很明显对你来说很明显!)的原因是在控制器中更新数组值时它没有在指令中反映出来。控制器从服务获取数据到数组,我想将该数组传递给指令以创建条形图。我已将代码的关键部分放在下面。

这是我的顶级HTML

<div dash-progress
    graph-data="{{dashCtrl.myProgress}}">
</div>
<div>
    Other Stuff
</div>

指令的模板HTML:

<div class="boxcontent" ng-show="dashCtrl.showProgress">
    <div class="chart-holder-lg">
        <canvas tc-chartjs-bar
            chart-data="progress"
            chart-options="options"
            height="200"
            auto-legend>
        </canvas>
    </div>
</div>

控制器:

angular
    .module('myApp')
    .controller('dashCtrl',['mySvc',
    function(mySvc) {

        var self = this;
        this.myProgress = [];

        this.getProgress = function() {
            //logic must be in the service !
            mySvc.getProgress().then(function(success) {
                self.myProgress = mySvc.progress;
            });
        };
    }]);

和指令:

angular
.module('myApp')
.directive('dashProgress', [function() {
    return {
        restrict: 'AE',
        templateUrl: 'components/dashboard/progress.html',
        scope: {
            graphData: '@'
            },
        link: function(scope,el,attrs) {
            scope.progress = {
                labels: ['Duration','Percent'],
                datasets: [
                    {
                    label: 'Duration',
                    data: [scope.graphData.duration]
                    },
                    {
                    label: 'Percent',
                    data: [scope.graphData.percent]
                    }                        
                ]
            };
            scope.options = { };
        }
    }        
}]);

如果我在控制器中设置myProgress对象的初始值,那么这些会反映在指令中,但是当它们返回到控制器时,我不会得到我需要的真实值从服务。

2 个答案:

答案 0 :(得分:0)

在你的指令范围内,而不是:

scope: {
  graphData: '@'
}

尝试使用:

scope: {
  graphData: '='
}

答案 1 :(得分:0)

  1. 将数组传递给带{{ }}的指令时,请勿使用=。它将在视图中呈现数组,而不是传递对指令范围的引用。
  2. 据我所知,@不仅是单向绑定,还是一次性绑定,主要用于字符串值(例如,在初始化指令时设置html属性)。如果你想使用@,首先应该将数据转换为JSON,然后将其传递给带有{{ }}的指令,然后在指令中再次解析它,并在任何更改之后 - 手动重新编译指令。但它会有点矫枉过正,不是吗?
  3. <强>结论

    只需从视图中删除大括号,然后使用=将值绑定到指令的范围。

    视图

    <div dash-progress
        graph-data="dashCtrl.myProgress">
    </div>
    

    指令

    scope: {
        graphData: '='
    },
    

    <强>更新

    再试一次。在dashCtrl中,用对象包装myProgress(您可以更改名称以便更自我解释 - 这只是一个示例):

    this.graphData = {
        myProgress: []
    }
    
    this.getProgress = function() {
        mySvc.getProgress().then(function(success) {
            self.graphData.myProgress = mySvc.progress;
        });
    }
    

    然后,将graphData传递给指令:

    <div dash-progress
        graph-data="dashCtrl.graphData">
    </div>
    

    最后,用scope.graphData替换每个scope.graphData.myProgress。这样,您可以确保scope.graphData.myProgress始终引用相同的数据,因为它是对象的属性。

    如果仍然无效,您可能需要使用观察程序并手动更新scope.progress的属性。