简体   繁体   中英

AngularJS directive two-way binding not working in Ionic

I cannot for the life of me wrap my head around this issue; I can't even figure out if it's a problem with AngularUI Router or Ionic itself.

I'm trying to accomplish two-way binding (ie scope: {data: "="} in the directive definition) with a custom AngularJS directive, it works perfectly as demonstrated by this jsfiddle but the same exact code used in my particular context (ie: I navigate through two states before I get to the page with the "Change data" button) doesn't ( jsfiddle here ).

SO prompts me to add some code to go along the jsfiddle links, so here goes the working version.

Page:

<!-- HTML -->
<body ng-app="myApp">
    <div ng-controller="MyCtrl">
        <signature data="signatureData"></signature>
        <button ng-click="changeData()">Change data!</button>
    </div>
</body>

Script:

//JS
angular.module("myApp", [])
.controller("MyCtrl", ["$scope", function ($scope) {
    $scope.changeData = function() {
        console.log("Outside directive:", $scope.signatureData);
        $scope.signatureData = "hello";
    };
}])
.directive("signature", [function() {
    var directiveDefinitionObject = {
        template: "<div>Don't mind me, I'm just a template...</div>",
        scope: {
            data: "="
        },
        controller: ["$scope", "$element", function($scope, $element) {
            $scope.data = "ciao";
            $scope.$watch("data", function(d) {
                console.log("Inside directive:", d);
            });
        }]
    };
    return directiveDefinitionObject;
}]);

/* Console output when clicking button:
Inside directive: ciao
Outside directive: ciao
Inside directive: hello
*/

Same code, though placed into context, in the second fiddle which is far too verbose to paste here (I apologize for that, I already skimmed it as much as possible but it's just to give an understanding of the issue in case it helps).

The console output, however, is:

/* Console output when clicking button:
Inside directive: ciao
Outside directive: undefined
*/

$scope.signatureData isn't defined before you call $scope.signatureData = "hello";

Try defining signatureData when you go to that controller...

.controller("JobRegistrationCtrl", ["$scope", function ($scope) {
    $scope.signatureData = "ciao"; //Now it's defined
    $scope.changeData = function() {
        console.log("Outside directive:", $scope.signatureData);
        $scope.signatureData = "hello";
    };
}])

I think I've pinpointed the issue.

Apparently AngularUI Router ( j'accuse! ) is responsible, since it does some wierd mumbo-jumbo with its scopes. I've updated both fiddles: working example , broken example . As you see, I've added in both fiddles a log of the involved scope's ids: the working example correctly states that the directive is two-way binding its models in scope 3 to the ones in its parent's scope (scope 2), and the controller which should see those changes is indeed number 2. The broken example, on the other hand, underlines the problem at hand: directive (scope 24) binds its models to parent scope (23) but the controller which should reflect changes is number 22, so there's a mismatch.

angular.module("myApp", [])
.controller("MyCtrl", ["$scope", function ($scope) {
    console.log("Parent's scope id is:", $scope.$id);
    $scope.changeData = function() {
        console.log("Outside directive:", $scope.signatureData);
        $scope.signatureData = "hello";
    };
}])
.directive("signature", [function() {
    var directiveDefinitionObject = {
        template: "<div>Don't mind me, I'm just a template...</div>",
        scope: {
            data: "="
        },
        controller: ["$scope", "$element", function($scope, $element) {
            console.log("Two-way binding between directive's scope (%d) and directive's parent scope (%d)", $scope.$id, $scope.$parent.$id);
            $scope.data = "ciao";
            $scope.$watch("data", function(d) {
                console.log("Inside directive:", d);
            });
        }]
    };
    return directiveDefinitionObject;
}]);

Result (console logs):

// Working version:
/*
Parent's scope id is: 2
Two-way binding between directive's scope (3) and directive's parent scope (2)
Inside directive: ciao
Outside directive: ciao
Inside directive: hello
*/

//Broken version
/*
Parent's scope id is: 22
Two-way binding between directive's scope (24) and directive's parent scope (23)
Inside directive: ciao
Outside directive: undefined
*/

Now I'm hoping some AngularUI Router expert swoops in and saves day.

following This

You have to use a "dotted" notation

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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