pirosikick's diary

君のハートにunshift

親Scopeの値は参照できるけど代入はうまくいかないよ父さん

Scope.$newのところを読んだけどやっぱりそうだった。

          Child = function() {}; // should be anonymous; This is so that when the minifier munges
            // the name it does not become random set of chars. This will then show up as class
            // name in the debugger.
          Child.prototype = this;
          child = new Child();
          child.$id = nextUid();

          // 省略

          return child;

なので、親scopeに定義してある変数に対して子scopeから値を代入したつもりでも、実際には子scopeに値を定義してしまっていて、次からはそっちを見るようになるのでうまくいかない。

例えば、↓では、visibleChildを使って子要素の表示・非表示を制御しているが、一度「Hide This」を押してしまうと、「Show Child」を押しても反応しない。

<body ng-app>
    <div class="parent" ng-controller="ParentCtrl" ng-init="visibleChild = true">
        
        <a ng-click="visibleChild = true">Show Child</a>
        
        <div class="child" ng-controller="ChildCtrl" ng-show="visibleChild">
            <h2>Child</h2>
            <a ng-click="visibleChild = false">Hide This</a>
        </div>
    </div>
</body>

親Scopeにsetterを用意する

直接代入することを避け、確実に親Scopeに値が入るようにする。

function ParentCtrl ($scope) {
  $scope.visibleChild = true;

  // visibleChildのsetter
  $scope.setVisibleChild = function (flag) {
    $scope.visibleChild = !!flag;
  }
}
<body ng-app>
    <div class="parent" ng-controller="ParentCtrl">
        
        <a ng-click="setVisibleChild(true)">Show Child</a>
        
        <div class="child" ng-controller="ChildCtrl" ng-show="visibleChild">
            <h2>Child</h2>
            <a ng-click="setVisibleChild(false)">Hide This</a>
        </div>
    </div>
</body>

本当はchildをdirective化してdirecvtive内にフラグを持ってうまいことやるのがいいのかもしれないが。directiveをもうちょい勉強して出直します。 もしくは$boardcastや$emitを使ってeventで操作するのがいいのか、誰かいい方法を知っていたら教えて下さいませ。