Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/75.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Angular 1.5中组件的DOM操作+_Javascript_Jquery_Angularjs - Fatal编程技术网

Javascript Angular 1.5中组件的DOM操作+

Javascript Angular 1.5中组件的DOM操作+,javascript,jquery,angularjs,Javascript,Jquery,Angularjs,我已经为下拉菜单创建了一个自定义指令。我想在下拉菜单上触发ng change事件时显示/隐藏UI元素 这是我代码的链接 调用了“oncarange”方法,但未根据选择隐藏或显示UI元素 我还在学习AngularJS,所以如果我采取了错误的方法,请告诉我 HTML标记 <div ng-app="RedBlack"> <select-car></select-car> <-- element directive <p ng-show="

我已经为下拉菜单创建了一个自定义指令。我想在下拉菜单上触发ng change事件时显示/隐藏UI元素

这是我代码的链接

调用了“oncarange”方法,但未根据选择隐藏或显示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>
select-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
<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>

您创建的组件应该被视为一个独立的组件。因此,在组件模板之外无法访问vm.showDataGrid和vm.disableRunButton

如果需要,您可以做两件事:

使选择成为事件 使组件使用ngModel,以便将其视为发出值的窗体控件。 我倾向于第二种方法。有关实现,请参见本指南:

核心是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在外部范围上定义控制器并将其传递到组件

<html ng-app="RedBlack" ng-controller="CarsController as vm">
    ...
    <select-car parent="vm"></select-car>
    ...
</html>
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>
组成部分

<html ng-app="RedBlack" ng-controller="CarsController as vm">
    ...
    <select-car parent="vm"></select-car>
    ...
</html>
angular
  .module('RedBlack.components', [])
  .component('selectCar', {
    restrict: 'E',
    templateUrl: 'select-car.html',
    bindings: { parent: "=" }, // = means two way data binding
    controllerAs: "vm"
  });
select-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
<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>

您使用的是一个组件,角度为1.5+;因此,它应该与页面控制器共享$scope(假设您有一个)。如果没有,请使用检索showDataGrid的方法创建一个空白页控制器-看看是否有效。@rrd我想使用CarsController作为控制器,因为还有其他方法。我真的不明白你说的空白页控制器是什么意思?可以在我的plunkr和revert中进行更改。加载DOM时,MainController中的select下拉列表的默认值为“undefined”。它只在我更改值时设置。哦,是的,这是一个小错误:我们可以发出选定的$onInit组件,只需添加vm即可。$onInit=function{vm.selected=vm.myCars[0];vm.onCarChanged{car:vm.selected}