【问题标题】:Angular - Add option to select using JqueryAngular - 添加选项以使用 Jquery 进行选择
【发布时间】:2018-02-26 06:46:22
【问题描述】:

我有一个指令将新选项添加到选择中。

为此我正在使用:

let opt: any = angular.element(
            '<option value="' + opcion.valor + '">' + opcion.texto + '</option>'
          );
          this.element.append(this.$compile(opt)(scope));

我不想使用模板,因为我不想要新的范围。

选项被添加到视图的列表中。但是当我选择其中一些时,选择的 ng-model 不会更新。它得到值 null

如何使用新的选项值刷新角度?

这是一个代码笔示例: 选择选项 X 不会反映在模型上。

奇怪的是,如果我链接到 angular 1.5.9,它可以工作,但从 angular 1.6.0 开始它就不行。

https://codepen.io/anon/pen/XemqGb?editors=0010

【问题讨论】:

    标签: javascript jquery html angularjs angularjs-directive


    【解决方案1】:

    如何使用新的选项值刷新角度?

    您不需要这样做。更新modeldata bindingdigest cicle 完成。

    Data binding 表示当您更改视图中的某些内容时,范围模型自动更新。

    您只需要更新您的范围digest cicle 正在处理剩下的工作。

    我建议您不要将jqueryangularJS 混用。

    您绝对应该在可能时尝试以angular 的方式做事。

    你不应该在 AngularJS 的顶部使用 jQuery,因为如果我们这样做,AngularJS digest 循环将不会运行使用 JQuery 进行角度 DOM 操作或范围变量操作。

    但是,您可以通过传递callback 函数来使用$scope.$apply() 方法执行此manually

    HTML

    <select ng-model="selectedValue">
      ....
    </select>
    

    JS

    $('select').change(function(){
        var value = $(this).val();
        var selectScope = angular.element($("select")).scope();
        selectScope.$apply(function(){
            selectScope.selectedValue=value;
        });
    });
    

    【讨论】:

    • 我了解有关 jquery 的警告。这就是为什么我只在指令中使用它。我想为选择添加新选项,但不为指令使用新模板。
    • @MartinIrigaray,是的,您可以通过手动应用$scope.$apply 方法来做到这一点。
    • @MartinIrigaray,我用一个可能的解决方案更新了我的答案,以更新选择的范围。
    • 我在 codepen 上放了一个例子,不适用于 angular 1.6.5。
    • 请注意,元素上的scope() 函数仅用于调试/测试目的,并不用于实际代码
    【解决方案2】:

    我想为选择添加新选项,但不为指令使用新模板

    在指令中使用compile 属性:

    myApp.directive('myList', function() {
       return {
            restrict: 'EA', //E = element, A = attribute, C = class, M = comment
             link: function ($scope, element, attrs) {
                 // ....
            }, //DOM manipulation
             compile: function(tElement, tAttrs) {
               tElement.append('<option value="10">Option Ten</option>');
            }
          }
      });
    

    Updated Demo Codepen


    [编辑 1]

    在更改外部模型字段后可以这样做吗?观察一个字段,然后添加选项?

    一点也不。 compile 在我们创建实例后立即调用一次。这是Angularjs编译指令的一个阶段

    但是,如果您想在基于外部流程的延迟后创造价值,为什么不使用ng-options - 您只需向对象列表添加新值,ng-options 将为您完成这项工作:

    Simple Example Fiddle

    $scope.items = [
        { value: "C", name: "Process C" },
        { value: "Q", name: "Process Q" }
    ];
     $timeout(function(){
        $scope.items.push({ value: "New", name: "Process New" });
     },3000);
    

    和 HTML:

    <select class="form-control" name="theModel" ng-model="theModel" 
            ng-options="c.value as c.name for c in items">
        <option value=""> -- </option>
      </select>
    

    【讨论】:

    • 在更改外部模型字段后可以这样做吗?观察一个字段,然后添加选项?
    • @MartinIrigaray 一点也不。 compile 在我们创建实例后立即调用一次。我认为这是您发布的问题的正确答案。但是如果你想在延迟之后创造价值,为什么你不想使用ng-options?您只需向对象列表添加新值,ng-options 将为您完成这项工作:jsfiddle.net/21on92dk
    【解决方案3】:

    最新的angularJSSelect value (read from DOM) is validated

    最好以标准方式使用 select,

    顺便说一句 - 如果你真的需要这个,通过如下装饰 selectDirective 来移除验证

    Codepen:https://codepen.io/anon/pen/NapVwN?editors=1010#anon-login

    myApp.decorator('selectDirective', function($delegate) {
        let originalCtrl = $delegate[0].controller.pop();
        $delegate[0].controller.push(function() {
          originalCtrl.apply(this, arguments);
          this.hasOption = function() { 
            return true; 
          }
        })
        return $delegate;
    });
    

    【讨论】:

      【解决方案4】:

      其实你没看懂的是数据绑定。这意味着当你在 $scope 中有东西时,你必须使用它。所以你的变量 $scope.opcion 必须是一个数组,因为它是一个选择。代码必须是这样的:

      /*
      AngularJS Basic Directives
      
      For More Examples AngularJS  
      
      http://mehmetcanker.com
      
      */
      
      var myApp = angular.module('example', []);
      
      myApp.controller('MyCtrl',['$scope', function($scope) {
      $scope.opcion = [1];
      }])
      
       //This directive doesn't individual scope so
       //Controller and Directive share same scope
       myApp.directive('myList', function() {
         return {
              restrict: 'EA', //E = element, A = attribute, C = class, M = comment
              link: function ($scope, element, attrs) {
                // add options
                $scope.opcion.join(2);
              } //DOM manipulation
          }
        });
      

      重要的部分是$scope.opcion = [1]$scope.opcion.join(value)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-01-30
        • 2012-06-03
        • 2016-12-25
        • 1970-01-01
        • 1970-01-01
        • 2011-06-01
        • 2012-10-07
        • 1970-01-01
        相关资源
        最近更新 更多