【问题标题】:How to prevent property change on Angular JS如何防止 Angular JS 上的属性更改
【发布时间】:2023-03-04 03:23:01
【问题描述】:

我在我的项目中使用 AngularJs,并且我的 viewModel 上有一个属性连接到下拉列表 ()

该下拉菜单默认选择一个空值,我想要的是防止用户在选择其他值后选择该空值。

我开始关注$watch,但我不知道是否有某种方法可以取消“更改该属性”,如下所示:

$scope.$watch('myProp', function (newVal, oldVal, scope) {
    if (newVal) { scope.preventDefault(); }
}

任何想法,这是基本想法,在更高级的开发中,我需要询问用户确认。

有什么想法吗?

【问题讨论】:

    标签: javascript angularjs


    【解决方案1】:

    我想要的是防止用户在选择其他值后选择该空值

    只要您最初没有为 ng-model 属性分配值,这应该会自动发生。所以使用下面显示的<select>,不要在你的控制器中初始化 $scope.selected_year:

    <select ng-model="selected_year" ng-options="year for year in years"></select>
    

    当列表最初显示时,Angular 会在 HTML 中添加这样的选项,因为 $scope.selected_year 当前没有设置为有效的选项/值:

    <option value="?" selected="selected"></option>
    

    选择一个有效选项后,该选项会神奇地消失,因此用户将无法再次选择它。试试这个fiddle

    如果 ng-model 属性在第一次显示选择列表时已经分配了有效值,那么您可以将控制器功能分配给 undocumentedng-change 参数:

    <select ... ng-change="preventUserFromDoingXzy()">
    

    在函数 preventUserFromDoingXzy() 中,你可以做你需要做的事情来控制用户可以选择什么,或者修改模型。

    【讨论】:

      【解决方案2】:

      您可以将ng-required 添加到选择中。 如果模型没有初始值,则将添加一个空选项,并在更改为有效值时删除该空选项

      EDITED jsFiddle 恢复到以前的值并包含 ng-change 指令。

      来自文档:

      当值变化来自模型时,不计算表达式。

      这对于不干扰更改侦听器并在恢复 $apply 函数中的旧值时创建无限循环很有用

      控制器

      $scope.options = [{value: 'abc'},{value: 'def'}];
      
      var confirmDialog = function(newVal, yes, no) {
          // obviously not a good way to ask for the user to confirm
          // replace this with a non blocking dialog
      
          //the timeout is only for the confirm since it's blocking the angular $digest
          setTimeout(function() {
              c = confirm('Is it ok? [' + newVal.value + ']');
              if(c) {
                  yes();
              }
              else {
                  no();
               }
          }, 0);
      };
      
      //Asking for confirmation example
      function Ctrl($scope) {
          $scope.options = [{value: 'abc'},{value: 'def'}];
      
          $scope.select = undefined;
          var oldSelect = undefined;
          $scope.confirmChange = function(select) {
              if(oldSelect) {
                  confirmDialog(select,
                       function() {
                          oldSelect = select;
                       },
                       function() {
                          $scope.$apply(function() {$scope.select = oldSelect;});
                      });
              }
              else {
                  oldSelect = select;
              }
          }
      }
      

      模板

      <div ng-controller="Ctrl">
        <select ng-model="select" ng-options="o.value for o in options"
                ng-required ng-change="confirmChange(select)">
        </select>
      </div>
      

      【讨论】:

        【解决方案3】:

        可能最简单、最干净的做法是添加一个初始选项并在其上设置disabled

        <option value="?" selected="selected" disabled></option>
        

        【讨论】:

          【解决方案4】:

          其实去掉空值比较容易。假设您有一个选项列表

          $scope.options = [{value: ''}, {value: 'abc'},{value: 'def'}];
          

          还有一个select

          <select ng-model="select" ng-options="o.value for o in options"></select>
          

          然后$watch模特:

          $scope.$watch('select', function(value) {
              if (value && value !== '') {
                  if ($scope.options[0].value === '') {
                      $scope.options = $scope.options.slice(1);
                  }
              }
          }, true);
          

          看到它在行动here

          PS 不要忘记 $watch 中的 objectEquality 参数,否则它将不起作用!

          【讨论】:

          • 在小提琴中似乎 ng-options 已经添加了一个空选项,因此无需手动添加一个
          • 确实,很奇怪。似乎 Angular 的选择已经做到了开箱即用
          • @LiviuT.: 看来,如果你不添加子选项,在 select 标记的正文中有一个空值,angular 会为你添加它。
          • 提前致谢,这是一个可能的解决方案,但是,我的问题转向不同的方向,我想取消用户更改属性的操作。就像在 jquery 上使用 o.preventDefault()
          • @asgoth,如果 ng-model 属性没有初始(有效)值,Angular 只会向 HTML 添加一个空选项。一旦选择了有效值,空选项就会神奇地消失。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-03-27
          • 1970-01-01
          • 1970-01-01
          • 2021-03-15
          相关资源
          最近更新 更多