简体   繁体   English

AngularJS指令范围未更新

[英]AngularJS directive scope not updating

Background 背景

I have created a directive to keep track of selection on my table. 我创建了一个指令来跟踪表上的选择。 The directive works with ng-repeat and adds a click event to every element created by the ng-repeat, when a user clicks on an element the directive updates the records selection atribute and sets the item as the selection on the controller scope for later use. 该指令与ng-repeat一起使用,并向ng-repeat创建的每个元素添加一个click事件,当用户单击某个元素时,该指令将更新记录选择属性,并将该项目设置为控制器作用域上的选择,以供以后使用。

Problem 问题

The parent scope (CampaignDetailCtrl) is not getting updated by my directive click event, the selection attribute is never changing an is always null. 我的指令click事件未更新父作用域(CampaignDetailCtrl),selection属性从不更改,并且始终为null。 I understand that using the scope: false causes the directive to use the parent scope but doesn't seem to work as planned. 我知道使用scope: false会导致指令使用父范围,但似乎无法按计划工作。

Question

How do I set the value of $scope.selection on my CampaignDetailCtrl from the directive? 如何通过指令在我的CampaignDetailCtrl上设置$ scope.selection的值?

Controller 控制者

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

//...

}]) }])

Directive 指示

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 的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>
...

Example

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

You have a shadowing issue. 你有一个影子问题。 You can read more about it at different places, but remember ng-repeat creates a new child scope for each item. 您可以在不同的地方阅读有关它的更多信息,但请记住ng-repeat为每个项目创建一个新的子范围。

To avoid scope shadowing, use a . 为避免作用域阴影,请使用. in your ngModel: 在您的ngModel中:

$scope.selection = {
    noShadow: null
};

// later: $scope.selection.noShadow

Working example here: http://jsbin.com/teyofukerilo/1/ 此处的工作示例: http : //jsbin.com/teyofukerilo/1/

While this will just work fine, it would be better to have isolated scopes on your selection and wrap them into a selected directive. 尽管这可以很好地工作,但最好将selection作用域隔离起来并将其包装到selected指令中。 The selected directive would then be 'required' by the others and communication between them would be managed by the controller defined on the selected directive. 然后,其他指令将“要求”所选指令,并且它们之间的通信将由在selected指令上定义的控制器进行管理。 You can read more about 'communicating' directives here: http://www.thinkster.io/angularjs/sMgLuIxf02/angularjs-directive-to-directive-communication https://docs.angularjs.org/guide/directive (see require attribute) 您可以在此处阅读有关“通信”指令的更多信息: http : //www.thinkster.io/angularjs/sMgLuIxf02/angularjs-directive-to-directive-communication https://docs.angularjs.org/guide/directive (请参阅require属性)

Let me know if you need help implementing it. 让我知道您是否需要帮助以实施它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM