【问题标题】:Angular-UI-Select ng-model not working with a simple variable on $scopeAngular-UI-Select ng-model 不适用于 $scope 上的简单变量
【发布时间】:2019-04-14 18:35:08
【问题描述】:

如何清除具有选定值的数组,以便值可以返回到选择中?

我有一个人员数组。人员数组值在选择中可用。当我选择名称时,它们将被转移到multipleDemo 数组。而且您不能从 select 中重新选择它们,因为它们会消失并移动到 multipleDemo 数组中。使用 Delete 按钮,我必须将 multipleDemo 数组中的所有元素(第一个元素除外)删除到 people 数组中。这样您就可以再次从选择中选择一个名称。函数$clearTag 出错。

预期行为: 示例:

  1. 选择:弗拉基米尔
  2. 出现标签弗拉基米尔
  3. 选择弗拉基米尔(您不能选择弗拉基米尔,因为他已经被选择)
  4. 单击删除。用 multipleDemo 数组剪切元素(标签)并将它们放入数组 people 中
  5. 您可以再次选择 Wladimir

这是我的代码:http://plnkr.co/edit/TPZjXkkSRrIc5ApzP07F?p=preview

index.html

<!DOCTYPE html>
<html lang="en" ng-app="demo">
<head>
  <meta charset="utf-8">
  <title>AngularJS ui-select</title>

  <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.18/angular.js"></script>
  <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.18/angular-sanitize.js"></script>
  <link rel="stylesheet" href="http://netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.css">

  <!-- ui-select files -->
  <script src="select.js"></script>
  <link rel="stylesheet" href="select.css">

  <script src="demo.js"></script>

  <!-- Select2 theme -->
  <link rel="stylesheet" href="http://cdnjs.cloudflare.com/ajax/libs/select2/3.4.5/select2.css">
  <link rel="stylesheet" href="http://cdnjs.cloudflare.com/ajax/libs/selectize.js/0.8.5/css/selectize.default.css">

  <style>
    body {
      padding: 15px;
    }

    .select2 > .select2-choice.ui-select-match {
      /* Because of the inclusion of Bootstrap */
      height: 29px;
    }

    .selectize-control > .selectize-dropdown {
      top: 36px;
    }
  </style>
</head>
<body ng-controller="DemoCtrl">
    
  <h3>Array of strings</h3>
  <button ng-click='clearTag()'>Delete</button>
  <ui-select tagging tagging-label="new tag" multiple ng-model="multipleDemo" 
  on-select="OnClickSelect($item)" on-remove="OnRemoveSelect($item)"
  theme="select2" ng-disabled="disabled" style="width: 300px;">
    <ui-select-match placeholder="Select name...">{{$item.name}}</ui-select-match>
    <ui-select-choices  repeat="item in people | filter:$select.search">
      {{item.name}}
    </ui-select-choices>
  </ui-select>
  <p>Selected: {{multipleDemo}}</p>
  <hr>  

</body>
</html>

demo.js

app.controller('DemoCtrl', function($scope, $http, $timeout) {
  $scope.multipleDemo =[];
    $scope.people = [
    { name: 'Adam',      email: 'adam@email.com',      age: 12, country: 'United States' },
    { name: 'Amalie',    email: 'amalie@email.com',    age: 12, country: 'Argentina' },
    { name: 'Estefanía', email: 'estefania@email.com', age: 21, country: 'Argentina' },
    { name: 'Adrian',    email: 'adrian@email.com',    age: 21, country: 'Ecuador' },
    { name: 'Wladimir',  email: 'wladimir@email.com',  age: 30, country: 'Ecuador' },
    { name: 'Samantha',  email: 'samantha@email.com',  age: 30, country: 'United States' },
    { name: 'Nicole',    email: 'nicole@email.com',    age: 43, country: 'Colombia' },
    { name: 'Natasha',   email: 'natasha@email.com',   age: 54, country: 'Ecuador' },
    { name: 'Michael',   email: 'michael@email.com',   age: 15, country: 'Colombia' },
    { name: 'Nicolás',   email: 'nicolas@email.com',    age: 43, country: 'Colombia' }
  ];

  $scope.OnClickSelect=function(item)
  {
   $scope.multipleDemo.push(item.name);
  }
  
  $scope.OnRemoveSelect = function(item) { 
   var index = $scope.people.indexOf(item.name);
   $scope.people.splice(index, 1); 
  }
  
  $scope.clearTag = function() {
    for(var i =0; i < $scope.multipleDemo.length; i++) {
      $scope.multipleDemo.splice($scope.multipleDemo[i], 1000);
      $scope.people.push($scope.multipleDemo[i]);
    }
  }

【问题讨论】:

  • 我不明白您所期望的行为。顺便说一句,您的 clearTag 函数不会被调用,因为您在 js 中将其声明为 $scope 但在 html 中将其称为 $ctrl跨度>
  • 功能清除标签。使用拼接方法切出想要放回人员数组中的元素
  • 您应该阅读ngController 指令的工作原理。您可以将$scope 注入您的控制器,如您所展示的那样,并在没有对象引用的情况下访问范围变量,或者您使用ng-controller="controller as $ctrl" 之类的东西并使用$ctrl.clearTag() 语法。您目前正在尝试同时使用两者。您的控制台中可能对此有错误;如果您需要进一步的帮助,请在您的问题中显示。
  • 我删除了$ctrl。我有 ng-click="clearTag()"。我在控制台中没有任何错误。

标签: javascript arrays angularjs angular-ui-select


【解决方案1】:

Angular-UI-Select 常见问题

ng-model 不能在 $scope 上使用简单变量

你不能写:

错误

<ui-select ng-model="multipleDemo"> <!-- Wrong -->
  [...]
</ui-select>

你需要写:

<ui-select ng-model="vm.multipleDemo"> <!-- Correct -->
  [...]
</ui-select>

有关详细信息,请参阅


更新

vm.multipleDemo 不起作用;我尝试$parent.multipleDemo - 它有效。我不明白$parent。为什么有效?

要使vm.multipleDemo 工作,控制器必须初始化vm 对象:

app.controller('DemoCtrl', function($scope, $http, $timeout) {
    $scope.vm = { multipleDemo: [] };

新的 AngularJS 开发人员通常没有意识到 ng-repeat、ng-switch、ng-view、ng-include 和 ng-if 都创建了新的子作用域,所以当这些指令被涉及。 (有关问题的快速说明,请参阅this example。)

遵循always have a '.' in your ng-models 的“最佳实践”可以轻松避免原语的这个问题 - 观看 3 分钟。 Misko 演示了 ng-switch 的原始绑定问题。

——What are the nuances of scope prototypal / prototypical inheritance in AngularJS?

避免使用$parent 来修复数据隐藏问题。这是一个脆弱的解决方案,因为控制器和ui-select 指令之间可能存在不止一个级别的范围层次结构。我认为$parent 的使用是code smell,这是更深层次问题的征兆。


更新 #2

我什么时候可以在视图中使用$ctrl,在控制器中使用this?

如果控制器是用“controller as”语法实例化的:

<body ng-controller="DemoCtrl as $ctrl">

    <ui-select ng-model="$ctrl.multipleDemo">
       <!-- -->
    </ui-select>

那么就不用$scope了:

app.controller('DemoCtrl', function($http) {
    this.multipleDemo =  [];

而且它避免了数据隐藏问题。

有关详细信息,请参阅

【讨论】:

  • vm.multipleDemo 不起作用;我尝试 $parent.multipleDemo - 它有效。我不明白 $parent。为什么有效?
  • 什么时候可以在视图中使用“$ctrl”,在控制器中使用“this”?
  • 是否可以遍历数组,不包括第一个元素(省略数组中的第一个元素)?
  • 这应该是new question。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多