【问题标题】:Hide div with AngularJS with Django-rendered template使用 AngularJS 和 Django 渲染模板隐藏 div
【发布时间】:2023-03-10 08:00:01
【问题描述】:

我有一个由 Django 模板标签呈现的 HTML 表单,我想使用 AngularJS 来操作它。

在我的模板(未渲染)中,我有:

<html>
   <body>
       {{ form.as_p }}
   </body>
</html>

这是 Django 呈现此模板的方式:

<html>
   <body>
      <form>
        <div id="div_id_street" class="ctrlHolder ">
        <label for="id_street">
            Street<span>*</span>
        </label>
        <input id="id_street" type="text" class="textInput textinput" name="street" maxlength="32">
        </div>
      </form>
   </body>
</html>

我想隐藏 div div_id_street,但由于 Django 生成 HTML 代码的方式,我无法在我的 HTML 中添加 ng-show 或 ng-hide 指令。 p>

是否可以在 AngularJS 控制器中显示/隐藏此 div?

谢谢!

【问题讨论】:

  • 是 Django 生成的 Angular 编译后的 HTML 吗?
  • HTML 是在 Angular 编译之前生成的。
  • 所以你可以让 Django 在某处添加“ng-controller='...'”,但不能让它在其他地方添加“ng-show='...'”?你能让 Django 向目标 div 添加一个类(这将是一个指令)吗?
  • 有可能,但要做到这一点,我需要更改部分 Django 核心。对我来说完美的解决方案是能够将 CSS 属性 display 更改为 none (隐藏 div)或删除此属性(显示 div) ,在 Angular 控制器中。
  • 我仍然缺少一些东西......在你的 Django 渲染模板中,ng-controller 在哪里?顺便说一句,可以从控制器内部修改 DOM。我只是首先想知道您是否可以连接控制器。还是想创建一个ctrlHolder 指令? (如果是这样,@CaioToOn 的答案将起作用。)

标签: django angularjs


【解决方案1】:

我错了。可以更改 Django 渲染表单的模板。

在定义 django 表单时,我可以更改每个字段的小部件,因此我可以将 Angular 指令放在小部件中。

例如:

# forms.py
class MyForm(forms.Form):
    street = forms.CharField(max_length=80, 
        widget=forms.TextInput(attrs={
            'ng-model': 'street',
            'ng-show': 'false',
            'ng-change': 'validateStreet()',})
        )

这将呈现为:

<div id="div_street" class="ctrlHolder">
    <label for="id_street">Street</label>
    <input ng-model="street" name="street" maxlength="80" ng-change="validateStreet()"
      ng-show="false" type="text" class="textInput textinput ng-valid ng-dirty"
      id="id_street">
</div>

所以在我的控制器中,我可以操纵整个字段。

【讨论】:

  • 好,我很高兴你让 Django 来代替它。您可能希望 ng-show 绑定到 $scope 属性。
  • 但是当我们在 Django 中使用表单实例更新数据时,angularJs 会删除初始值
【解决方案2】:

是否可以在 AngularJS 控制器中显示/隐藏此 div?

是的,但这“与 Angular 方式背道而驰”——Misko。注入 $element,然后使用选择器来查找和操作。 $element 设置为定义控制器的元素。

function MyCtrl($scope, $element) {
  $scope.show = false;
  $scope.$watch('show', function (value) {
    if (value) {
        $element.find('#div_id_street').show();
    } else {
        $element.find('#div_id_street').hide();
    }
  })
}

Fiddle -- 在这个小提琴中我使用了 ng-controller。

【讨论】:

    【解决方案3】:

    如果您无法修改模板,则不要向该特定 DIV 添加类以将其添加为 ng-show,而是应该创建一个指令来处理此 DOM 操作。您不应该在控制器内进行 DOM 操作。作为stated by the DOCs

    不要将控制器用于:

    • 任何类型的 DOM 操作——控制器应该只包含 商业逻辑。 DOM 操作——一个对象的表示逻辑 应用程序——以难以测试而闻名。放任何 将逻辑表示到控制器中会显着影响可测试性 的业务逻辑。 Angular 为自动 DOM 提供数据绑定 操纵。如果您必须执行自己的手动 DOM 操作, 将表示逻辑封装在 [directives]http://docs.angularjs.org/guide/directive) 中。
    • ...

    我建议您 $watch 所需的属性,并在指令的 link 函数内手动显示/隐藏元素。

    【讨论】:

    • 同意。这不是必须使用 AngularJS 的方式。但我找到了改变我的模板的方法。这是缺乏 Django 知识 :-) 我会在这里发布解决方案。
    猜你喜欢
    • 2016-01-14
    • 2017-07-04
    • 2016-09-06
    • 2022-07-22
    • 2017-09-27
    • 2016-12-07
    • 1970-01-01
    • 2018-11-25
    • 2011-09-28
    相关资源
    最近更新 更多