2016-12-22 9 views
3

ドロップダウンのカスタムディレクティブを作成しました。そのドロップダウンでng-changeイベントが発生したときにUI要素を表示/非表示にしたい。コンポーネントからのDOM操作Angle 1.5 +

これは私のコードへのplunkrのリンクです。

'onCarChange()'メソッドが呼び出されていますが、選択に基づいてUI要素が非表示または表示されていません。

私はまだAngularJSを勉強していますので、間違ったアプローチをとっている場合は、親切に教えてください。

HTMLマークアップ

<div ng-app="RedBlack"> 
    <select-car></select-car> <-- element directive 
    <p ng-show="vm.showDataGrid">DATA GRID</p> 
    <button ng-show="!vm.disableRunButton">Run Button</button> 
</div> 

AngularJSコード

angular 
    .module('RedBlack', []) 
    .component('selectCar', { 
     restrict: 'E', 
     templateUrl: 'select-car.html', 
     bindings: { 

     }, 
     transclude: true, 
     controller: CarsController, 
     controllerAs: 'vm', 
     replace: true 
    }) 
    .controller("CarsController", CarsController); 

function CarsController() { 
    var vm = this;  
    vm.showDataGrid = true; 
    vm.disableRunButton = true; 
    vm.myCars = { 
    options: [ 
     { id: '1', name: 'LaFerrari' }, 
     { id: '2', name: 'Porsche 918' }, 
     { id: '3', name: 'McLaren P1' } 
    ], 
    selectedCar: { id: '2', name: 'Porsche 918' } 
    };  
    vm.onCarChange = onCarChange; 

    function onCarChange() { 
    console.log("Called onCarChange()"); 
    vm.showDataGrid = false; 
    vm.disableRunButton = false; 
    return true; 
    } 

} 

選択-car.html

<div> 
    <select class="form-control" ng-options="option.name for option in vm.myCars.options track by option.id" 
    ng-model="vm.myCars.selectedCar" 
    ng-change="vm.onCarChange()"> 
    </select> 
</div 
+0

あなたはコンポーネント、角張っている1.5+使っているならなければなりません。だからあなたは$ 1スコープをページコントローラと共有するべきです(あなたが持っていると仮定して)。そうでない場合は、空のページコントローラを作成して、showDataGridを取得するメソッドを作成します。 – rrd

+0

@rrd他のメソッドがあるので、コントローラとしてCarsControllerを使いたいです。空のページコントローラが何を意味するのか分かりません。あなたは私のplunkrを変更して元に戻すことができますか? – overlord

答えて

0

を作成したコンポーネントが孤立コンポーネントとして見られるべきです。したがって、vm.showDataGridおよびvm.disableRunButtonは、コンポーネントテンプレートの外部にはアクセスできません。これを希望する場合は

は、次の2つのことを行うことができます:イベント

  • 選択を行い

    1. を、それは価値を発するフォームコントロールとみなすことができるように、コンポーネントを使用ngModelしてください。

    私は第2のアプローチを好む傾向があります。実装のために、このplunkrを参照してください。https://plnkr.co/edit/RG51ADtvHuRSJDUMv6mV?p=preview

    コアはCarsControllerの新しい実装である:

    function CarsController() { 
    
    } 
    
    CarsController.prototype.onCarChange = function() { 
        // Because of the ng-model on the <select>, this.myCars.selectedCar is already 
        // up to date. 
        this.ngModel.$setViewValue(this.myCars.selectedCar); 
    } 
    
    
    CarsController.prototype.$onInit = function() { 
        var vm = this; 
    
        vm.ngModel.$render = function() { 
        // This is called when the bound model value changes from external sources 
        // vm.ngModel.$modelValue contains the new value, it may be a completely different 
        // object, so set the selected to the one in the options 
        vm.myCars.selectedCar = vm.myCars.options.find(function(item) { 
         return vm.ngModel.$modelValue && item.id == vm.ngModel.$modelValue.id; 
        }); 
        } 
    
    
    
        vm.showDataGrid = true; 
        vm.disableRunButton = true; 
    
        vm.myCars = { 
        options: [ 
         { id: '1', name: 'LaFerrari' }, 
         { id: '2', name: 'Porsche 918' }, 
         { id: '3', name: 'McLaren P1' } 
        ], 
        selectedCar: { id: '2', name: 'Porsche 918' } 
        }; 
        // Initialize the ngModel value 
        this.onCarChange(); 
    } 
    

    その後、あなたは、単にHTMLから新しいコンポーネントにNG-モデルを使用することができます。

    <select-car ng-model="selectedCar"></select-car> 
    
  • 1

    コンポーネントのスコープは常に分離されます。 2つの選択肢があります。オプション1は代わりにディレクティブを使用することです。 (plunkr

    コンポーネントを使用する場合は、値を渡します。 (plunkr)モデル(車など)のようなものをコンポーネントに渡し、ドロップダウンを変更するためのイベントを使用する方が良いでしょうが、その点が分かります。

    1)成分

    angular 
        .module('RedBlack.components', []) 
        .component('selectCar', { 
        restrict: 'E', 
        templateUrl: 'select-car.html', 
        bindings: { parent: "=" }, // = means two way data binding 
        controllerAs: "vm" 
        }); 
    

    3)を調整テンプレートの範囲を単離する

    <html ng-app="RedBlack" ng-controller="CarsController as vm"> 
        ... 
        <select-car parent="vm"></select-car> 
        ... 
    </html> 
    

    2)バインド値を外側のスコープでコントローラを定義し、コンポーネントに渡し

    <div> 
        <select class="form-control" ng-options="option.name for option in vm.parent.myCars.options track by option.id" 
        ng-model="vm.parent.myCars.selectedCar" 
        ng-change="vm.parent.onCarChange()"> 
        </select> 
    </div> 
    
    1

    ここにあなたのコードのリファクタがあります

    PLUNKER CODE

    index.htmlを

    <!DOCTYPE html> 
    <html ng-app="RedBlack"> 
    
        <head> 
        <link rel="stylesheet" href="style.css"> 
        <script src="https://opensource.keycdn.com/angularjs/1.5.8/angular.min.js"></script> 
        <script src="car.module.js"></script> 
        <script src="selectCar.directive.js"></script> 
        <script src="script.js"></script> 
        </head> 
    
        <body> 
        <div id="app" ng-controller='MainController as vm'> 
        <h1>Hello a car!</h1> 
        <select-car 
         on-car-changed='vm.carChange(car)'> 
        </select-car> 
    
        <p ng-show="!vm.showDataGrid">DATA GRID</p> 
    
        <p>{{ vm.selected.name }}</p> 
    
        <button ng-show="!vm.disableRunButton">Run Button</button> 
        </div> 
        </body> 
    
    </html> 
    

    car.module.js //主として

    angular 
        .module('RedBlack.cars', []) 
        .controller("MainController", MainController); 
    
    function MainController() { 
    
        var vm = this; 
    
        vm.showDataGrid = true; 
        vm.disableRunButton = true; 
    
        vm.carChange = carChange; 
    
        function carChange(car) { 
    
        console.log("Called onCarChange()"); 
        console.log(car) 
    
        vm.selected = car.name 
        vm.showDataGrid = false; 
        vm.disableRunButton = false; 
        } 
    
    } 
    

    成分

    選択-car.html

    <div> 
        <select 
        class="form-control" 
        ng-options="item as item.name for item in vm.myCars track by item.id" 
        ng-model="vm.selected" 
        ng-change="vm.onCarChanged({car: vm.selected})"> 
        </select> 
    </div> 
    

    selectCar.directive.js // AS SELECT-car.component.js

    angular 
        .module('RedBlack.components', []) 
        .component('selectCar', { 
         templateUrl: 'select-car.html', 
         bindings: { 
         onCarChanged: '&' 
         }, 
         controller: [function() { 
         var vm = this; 
    
          vm.myCars = [ 
           { id: 1, name: 'LaFerrari' }, 
           { id: 2, name: 'Porsche 918' }, 
           { id: 3, name: 'McLaren P1' } 
          ]; 
    
          vm.selected = vm.myCars[0] 
         }], 
         controllerAs: 'vm' 
        }); 
    
    +0

    DOMがロードされるとき、MainControllerのselectドロップダウンのデフォルト値は 'undefined'です。値を変更した場合にのみ設定されます。 – overlord

    +0

    ああ、ちょっとバグだよ。選択した '$ onInit'コンポーネントを出力できる。 vm。$ onInit = function(){ vm.selected = vm.myCars [0]; vm.onCarChanged({car:vm.selected}) } –