How to modify scope from within a directive in AngularJs

后端 未结 2 1257
花落未央
花落未央 2020-11-29 07:05

I need to modify a root scope attribute from within a callback inside a directive. But the directive is in a inner scope created by a switch directive.

HTML

相关标签:
2条回答
  • 2020-11-29 08:09

    I updated the fiddle, basically had to go to the parent to get the right "selected" variable, also used the isolate scope = to get two way binding between the value passed in and the internal model.

    http://jsfiddle.net/nJ7FQ/2/

    angular.module('app', [])
    
        .directive("customTag", [function () {
        return {
            restrict: "E",
            replace: true,
            template: "<input type='button' value='Click me' />",
            scope: {model:'='},
    
            link: function (scope, element, attrs) {
                element.bind('click', function () {
                    scope.model[attrs.selectedItem] = "New value";
                    scope.$apply();
                });
            }
        };
    }]);
    
    function AppController($scope) {
        $scope.selected = 'Old value';
    }
    

    and the HTML

    <div ng-app="app" ng-controller='AppController'>
        <p>Selected: {{ selected }}</p>
        <div ng-switch on="selected">
            <div ng-switch-default>
                <p>Item: {{ selected }}</p>
                <custom-tag selected-item="selected" model="$parent" />
            </div>
            <div ng-switch-when="New value">
                <p>Worked</p>
            </div>
        </div>
    </div>
    

    Updated the fiddle to use your original reading of the property from the attribute: http://jsfiddle.net/nJ7FQ/4/

    0 讨论(0)
  • 2020-11-29 08:10

    I improved the jsfiddle a bit:

    angular.module('app', [])
    
        .directive("customTag", ['$parse', function ($parse) {
        return {
            restrict: "E",
            replace: true,
            template: "<input type='button' value='Click me' />",
    
            link: function (scope, element, attrs) {
                element.bind('click', function () {
                    scope.$apply(function () {
                        $parse(attrs.selectedItem).assign(scope.$parent, "New value");
                    });
                });
            }
        };
    }]);
    
    function AppController($scope) {
        $scope.selected = { 'foo': 'Old value' };
    }
    

    http://jsfiddle.net/nJ7FQ/15/

    This way, the scope value, you want to change can also be an object property like selected.foo in the example. Also, I removed the scope parameter and told the directive to always use the parent scope. And finally I wrapped the click handler into the $apply callback (see here for example). Better would be, of course, to use ngClick instead of the element.bind().

    0 讨论(0)
提交回复
热议问题