2014-10-07 70 views
1

DEMOAngularJS指令數據綁定不起作用

這裏是兩個指令我有,my-inputanother-directive的簡化版本:

HTML:

<body ng-controller="AppCtrl"> 
    <another-directive> 
    <my-input my-input-model="data.firstName"></my-input> 
    </another-directive> 
</body> 

JS:

.directive('myInput', function() { 
    return { 
    restrict: 'E', 
    replace: true, 
    scope: { 
     model: '=myInputModel' 
    }, 
    template: '<input type="text" ng-model="model">' 
    }; 
}).directive('anotherDirective', function($compile) { 
    return { 
    restrict: 'E', 
    scope: {}, 
    compile: function(element) { 
     var html = element.html(); 

     return function(scope) { 
     var output = angular.element(
      '<div class="another-directive">' + 
      html + 
      '</div>' 
     ); 

     $compile(output)(scope); 
     element.empty().append(output); // This line breaks the binding 
     }; 
    } 
    }; 
}); 

正如您在demo中看到的,如果我刪除element.empty().append(output);,則一切正常,即輸入字段中的更改反映在控制器的data中。但是,添加這條線,打破了綁定。

這是怎麼發生的?

PLAYGROUND HERE

回答

2

element.empty()呼叫被摧毀的element所有子節點。在這種情況下,elementanother-directive的HTML代表。當你打電話給.empty()時,它試圖銷燬它的子指令my-input以及任何與它一起使用的作用域/數據綁定。

一個與你的例子有點不相干的筆記。你應該考慮使用transclusion來在指令中嵌套html,就像你正在使用another-directive一樣。你可以在這裏找到更多的信息:https://docs.angularjs.org/api/ng/service/ $編譯#transclusion

1

我認爲一點點的情況下,你試圖做得很好會有所幫助。我假設你想在另一個指令(某種父窗格)中包裝my-input指令。你可以用ng transclude完成這個。即

angular.module('App', []).controller('AppCtrl', function($scope) { 
    $scope.data = { 
    firstName: 'David' 
    }; 
    $scope.test = "My test data"; 
}).directive('myInput', function() { 
    return { 
    restrict: 'E', 
    replace: true, 
    scope: { 
     model: '=myInputModel' 
    }, 
    template: '<input type="text" ng-model="model">' 
    }; 
}).directive('anotherDirective', function($compile) { 
    return { 
    restrict: 'E', 
    transclude: true, 
    scope: {}, 
    template : '<div class="another-directive"><div ng-transclude></div></div>' 
    }; 
}); 
0

它的工作原理,如果你需要ngModel

}).directive('anotherDirective', function($compile) { 
return { 
    restrict: 'E', 
    require:'ngModel', 
    scope: {}, 
...