AngularJS 在模板中使用 ng-if 时,父 ng-model 未与自定义指令绑定

AngularJS parent ng-model is not binding with custom directive when using ng-if in the template

我正在尝试创建一个自定义指令来呈现下拉菜单(select)。

app.directive("uiDropdown", function () {
    return {
        restrict: "E",
        replace: true,
        scope: {
            'model': '=ngModel',
            'readOnly':'=?'

        },
            templateUrl : 'template/dropdownTemplate.html',
        link: function (scope, elem, attrs) {
        }
    };
});

模板是

<span ng-if="!readOnly">
<select ng-model="model"  >   
    <option value="1">One</option>   
    <option value="2">Two</option>   
    <option value="3">Three</option>
</select>

Html 使用指令的代码是

  <ui-dropdown ng-model="region"  read-only='readOnly'>

plunker代码是plunker

如果我从模板文件中删除代码 'ng-if="!readOnly"',它会按预期工作。如果我从 "ng-if" 更改为 "ng-show",它也会正常工作。

我是不是漏掉了什么?实际上,该指令应该比本例中显示的功能多得多。我更喜欢使用 ng-if 而不是 ng-show。请帮助解决这个问题。

ng-if 包含一个要么为真要么为假的陈述 尝试

 <ui-dropdown ng-model="region"  read-only='true'>

这与 ng-if 创建自己的子作用域然后您直接使用基元这一事实有关。 ng-if 实际上会创建一个与父级无关的本地 model 布尔值。这将是 ng-if 的一个问题,即使它也没有通过指令使用。

您可以通过传递对象和 reading/setting 该对象的值来解决此问题。这是一个简单的示例,显示您的 ng-if 问题与指令无关,然后是如何使用对象解决此问题:

angular.module('app', [])
  .controller('ctrl', function($scope) {
    $scope.readOnly = false;
    $scope.primitive = "1";
    $scope.object = {
      selectedValue: "1"
    };
  })
  .directive('uiDropdown', function() {
    return {
      restrict: 'E',
      templateUrl: 'dropdownTemplate.html',
      scope: {
        model: '=ngModel',
        fieldName: '@',
        readOnly: '=?'
      }
    }
  });
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
<div ng-app="app" ng-controller="ctrl">
  <div>
    <label>Readonly: <input type="checkbox" ng-model="readOnly" /></label>
  </div>
  <div>
    <h1>ng-if with primitive - no directive</h1>
    <h2>This will not work</h2>
    <div>
      Value: {{ primitive }}
    </div>
    <div ng-if="!readOnly">
      <select ng-model="primitive">
        <option value="1">One</option>
        <option value="2">Two</option>
        <option value="3">Three</option>
      </select>
    </div>
  </div>
  <div>
    <h1>ng-if with object - directive</h1>
    <h2>This will work</h2>
    <div>
      Value: {{ object.selectedValue }}
    </div>
    <ui-dropdown ng-model="object" read-only="readOnly" field-name="selectedValue"></ui-dropdown>
  </div>
  <script type="text/ng-template" id="dropdownTemplate.html">
    <div ng-if="!readOnly">
      <select ng-model="model[fieldName]">
        <option value="1">One</option>
        <option value="2">Two</option>
        <option value="3">Three</option>
      </select>
    </div>
  </script>
</div>