2013-07-10 32 views
26

我需要修改指令中回調中的根範圍屬性。但是該指令位於由switch指令創建的內部作用域中。如何在AngularJs中的指令中修改範圍

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" /> 
     </div> 
     <div ng-switch-when="New value"> 
      <p>Worked</p> 
     </div> 
    </div> 
</div> 

的JavaScript

angular.module('app', [])  
    .directive("customTag", [function() { 
    return { 
     restrict: "E", 
     replace: true, 
     template: "<input type='button' value='Click me' />", 

     link: function (scope, element, attrs) { 
      element.bind('click', function() { 
       scope[attrs.selectedItem] = "New value"; 
       scope.$apply(); 
      }); 
     } 
    }; 
}]); 

function AppController($scope) { 
    $scope.selected = 'Old value'; 
} 

小提琴:http://jsfiddle.net/nJ7FQ/

我的目標是能夠在選定區域顯示 「新價值」。 我該如何完成我想要做的事情?我究竟做錯了什麼?

此外,因爲我正在嘗試製作組件。有沒有辦法做到這一點,但有一個孤立的範圍?

回答

19

我更新了小提琴,基本上不得不去父母來獲得正確的「選定」變量,也使用隔離範圍=獲得傳入的值和內部模型之間的雙向綁定。

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'; 
} 

和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> 

已更新爲使用原來的從屬性的屬性的讀取小提琴: http://jsfiddle.net/nJ7FQ/4/

+0

我更喜歡你的第一個解決方案(http://jsfiddle.net/nJ7FQ/2/)它似乎更清潔。但是,爲什麼我應該使用$ parent.selected,據我所知,子範圍繼承父級的所有屬性? – Fernando

+1

那麼如果你改變了繼承的選擇變量,它不會更改父範圍選定變量,通過上移到父級並更改該範圍上的變量,那麼當讀取子選定值時,它將變爲家長。如果更改子範圍的選定屬性,它將成爲子範圍上的新屬性,不再繼承。 (我知道它很混亂)如果你想Google它,這是Javascript原型繼承。 – shaunhusain

+0

非常清楚!非常感謝。 – Fernando

15

我改進了的jsfiddle了一下:

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/

這種方式,範圍值,要更改,也可以像在例如selected.foo的對象屬性。此外,我刪除了範圍參數,並告訴該指令始終使用父範圍。最後,我將點擊處理程序包裝到$apply回調中(例如,參見here)。當然,最好使用ngClick而不是element.bind()

+0

賓果!指定父範圍的好解決方案。理想的東西就像情緒 – saike