[英]DOM Manipulation from Component in Angular 1.5+
我已經為下拉列表創建了一個自定義指令。 我想在該下拉列表上觸發ng-change事件時顯示/隱藏UI元素。
這是我的代碼的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
組件的范圍始終是隔離的。 你有兩個選擇。 選項一是使用指令代替。 ( plunkr )
angular
.module('RedBlack.components', [])
.directive('selectCar', function() {
return {
restrict: 'E',
templateUrl: 'select-car.html',
transclude: true,
controller: CarsController,
controllerAs: 'vm'
};
});
如果要使用組件,則一個選項是將值傳遞給它。 ( plunkr )請注意,最好將類似模型(例如汽車)的東西傳遞到組件中並使用事件來更改下拉列表,但是你明白了。
1)在外部范圍上定義控制器並將其傳遞給組件
<html ng-app="RedBlack" ng-controller="CarsController as vm">
...
<select-car parent="vm"></select-car>
...
</html>
2)綁定值以隔離組件的范圍
angular
.module('RedBlack.components', [])
.component('selectCar', {
restrict: 'E',
templateUrl: 'select-car.html',
bindings: { parent: "=" }, // = means two way data binding
controllerAs: "vm"
});
3)調整模板
<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>
這是我的代碼重構
的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 //必須變為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'
});
您創建的組件應被視為一個獨立的組件。 因此,組件模板外部無法訪問vm.showDataGrid
和vm.disableRunButton
。
如果需要,您可以做兩件事:
我傾向於采用第二種方法。 請參閱此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-model:
<select-car ng-model="selectedCar"></select-car>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.