AngularJS指令范围不更新

时间:2014-08-27 04:54:57

标签: javascript angularjs

背景

我创建了一个指令来跟踪我桌子上的选择。该指令与ng-repeat一起使用,并为ng-repeat创建的每个元素添加一个click事件,当用户点击一个元素时,该指令更新记录选择属性,并将该项设置为控制器作用域上的选择供以后使用

问题

我的指令点击事件未更新父作用域(CampaignDetailCtrl),选择属性永远不会更改,因此始终为null。我知道使用scope: false会导致指令使用父作用域,但似乎没有按计划工作。

问题

如何从指令设置我的CampaignDetailCtrl上$ scope.selection的值?

控制器

app.controller('CampaignDetailCtrl', ['$scope', 'CampaignService', '$stateParams', '$modal', function ($scope, CampaignService, $stateParams, $modal) {
$scope.selection = null;

//...

}])

指令

app.directive('selection', function () {
var directive = {
    restrict: 'A',
    scope: false,
    link: function (scope, element, attrs) {
        var selected_class = 'selected';

        var repeat_line = attrs.ngRepeat;

        if (!repeat_line) {
            throw 'selection must be used along side ngRepeat';
        }

        var repeat_parts = repeat_line.split(' in ');
        var selected_item = scope.$eval(repeat_parts[0]);

        scope.$watch(scope.selection, function(newVal, oldVal) {

        });

        /**
         * Item click handler
         */
        var handleClick = function (event) {
            selected_item.selected = !selected_item.selected;
            scope.selection = selected_item;

            if(selected_item.selected) {
                element.addClass(selected_class);
            } else {
                element.removeClass(selected_class);
            }
        };

        element.on('click', handleClick);
    }
};

return directive;

});

HTML

<div ng-controller="CampaignDetailCtrl">
...

<table>
    <thead>
    <tr>
        <th>...</th>
    </tr>
    </thead>
    <tbody>
    <tr selection ng-repeat="channel in record.channels" ng-dblclick="edit(channel)">
        <td>{{...}}</td>
    </tr>

    </tbody>
</table>
...

实施例

参见简单的jsBin示例:http://jsbin.com/xoxez/3/

1 个答案:

答案 0 :(得分:2)

你有一个阴影问题。您可以在不同的地方阅读有关它的更多信息,但请记住ng-repeat为每个项目创建一个新的子范围。

要避免范围遮蔽,请在ngModel中使用.

$scope.selection = {
    noShadow: null
};

// later: $scope.selection.noShadow

这里的工作示例:http://jsbin.com/teyofukerilo/1/

虽然这样可以正常工作,但最好在selection上放置隔离范围并将它们包装到selected指令中。然后,其他人将“需要”所选指令,并且它们之间的通信将由selected指令上定义的控制器进行管理。您可以在此处阅读有关“沟通”指令的更多信息: http://www.thinkster.io/angularjs/sMgLuIxf02/angularjs-directive-to-directive-communication https://docs.angularjs.org/guide/directive(请参阅require属性)

如果您需要帮助,请与我们联系。