Angularjs: How to update parent scope in directive without using isolated scope when the attribute is passed in within ngRepeat

StackOverflow https://stackoverflow.com//questions/22033421

Вопрос

I have a simple angularjs directive that uses JQuery to convert a template to a draggable dialog

var myApp = angular.module("myApp", []);
myApp.controller('myCtrl', function ($scope) {
    $scope.tasks = [{
        name: 'learn angular',
        show: false
    }, {
        name: 'build an angular app',
        show: false
    }];
    $scope.showBox = function (taskname) {
        for (var i = 0; i < $scope.tasks.length; i++) {
            if ($scope.tasks[i].name === taskname) {
                $scope.tasks[i].show = !$scope.tasks[i].show;
            }
        }
    }
});
myApp.directive("draggableDialog", function () {
    return {
        template: 'task: {{task.name}}',
        link: function (scope, element, attrs) {
            element.dialog({
                title : "My Dialog",
                autoOpen: false
            });
            element.bind("dialogclose", function () {
                if (!scope.$$phase) {
                    scope.$apply(function () {
                        scope[attrs.draggableDialog] = false; //here is the problem
                    });
                }
            });
            scope.$watch(attrs.draggableDialog, function (v) {
                if (v) {
                    element.dialog("open");
                } else {
                    element.dialog("close");
                }

            });
        }
    }
});

I am using this directive in a ngRepeat

<div>
     <h2>Draggable Dialog</h2>
    <div ng-controller="myCtrl">
        <ul class="unstyled">
            <li ng-repeat="task in tasks">
                <button ng-click="showBox(task.name)">show {{task.name}}</button>{{task.show}}
                <div draggable-dialog="task.show">test</div>
            </li>
        </ul>
    </div>
</div>

Refer to this fiddle: http://jsfiddle.net/tianhai/BEtPk/#base

When the user manually close the dialog, I can detect the event and I want to set $scope.task[i].show in myCtrl to false. How can I do it? I am not able to use isolated scope two way binding as I am using this directive together with another directive also taking in $scope.task.

Это было полезно?

Решение

You have attrs.draggableDialog set to "task.show" so when you do scope[attrs.draggableDialog] = false you end up with a element attached to scope that you could access with scope['task.show'] which is different than scope['task']['show'] or scope.task.show

To generically set a parent variable to false you need to eval a string containing the assignment. For you it would look like this:

scope.$eval(attrs.draggableDialog + ' = false;');

Hope this helped

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top