在POST之后处理Angular控制器到指令的成功/错误DOM操作

时间:2014-11-21 05:11:38

标签: javascript html angularjs angularjs-directive

我在这里和那里一直在学习角度,但是我不太了解从服务器处理成功/错误响应的角度方式。典型的jQuery方法是:

  • 从表单
  • 序列化数据
  • $。将数据发布到服务器
  • 服务器验证数据,以成功或错误数据作出响应
  • 使用jQuery来maniuplate DOM以显示来自服务器的成功/错误数据。

在角度,我们有操纵DOM的指令,我们有控制器来处理模型。假设我们有以下内容:

form.html

<div ng-controller="myController">
    <span class="hidden success-message"></span>
    <form>
        <label> Name </label>
        <input type="text" name="name" ng-model="name">
        <span class="name-error hidden"></span>
        <label> Occupation </label>
        <input type="text" name="occupation" ng-model="occupation">
        <span class="occupation-error hidden"></span>

        <input submit-directive type="submit" id="submit" value="Submit">
    </form>
</div>

app.js

angular.module('app', []).controller('myController', [$scope, $http, function($scope, $http) {
    $scope.name = "";
    $scope.occupation = "";

    $scope.doSubmit: function(formData) {
        $http.post("/save", formData)
        .success(function(response) {
            $scope.name = response['name']
            $scope.occupation = response['occupation']

            // How to pass success messages back to directive?

        }.fail(function(err) {

            // How to pass error messages back to directive?

        }
    }
});

angular.module('app', []).directive('submit-directive', function() {
    return {
        restrict: 'A',
        link: function(scope, element, attrs) {
             element.click(function() {
                 // Pass form data back to controller
                 scope.$apply('doSubmit(\"' + $("form").serialize() +'\")');
             });

             // How do I get the success/fail results from the Controller so that I can manipulate the DOM?

        }
    };
});

此处,用户输入了他们的nameoccupation。提交后,该指令获取表单数据并将其提供给控制器以获取POST请求。返回响应时,指令应显示成功消息或显示错误消息。

我不清楚如何将控制器的响应传递给DOM操作的指令。

我想到的唯一方法是创建$watch

// in controller
$scope.isFormPostSuccess = false;
$scope.formResponse = null;
// ....
.success(function(response) {
     $scope.isFormPostSuccess = true;
     $scope.formResponse = response;
}.fail(function(err) {
     $scope.isFormPostSuccess = false;
     $scope.formResponse = err;
}

然后在指令中,我会观察这些变量的变化并采取相应的行动。然而,这样做的方式感觉非常混乱,并且对于较大的应用程序或具有许多独立形式时似乎不能很好地扩展。我也可以将所有DOM操作移动到控制器中,但这只是糟糕的设计。

适当的角度方式是什么?

1 个答案:

答案 0 :(得分:3)

实际上,所谓的&#34; Angular方式&#34;应该将模型($scope.foo)的使用与指令(如ng-modelng-bindng-show等,或您的自定义指令)相结合,以实现目标一个DOM操作。它不喜欢在您的控制器中手动启动DOM操作,而是在控制器中更改模型,DOM将在指令的帮助下相应地更新自己。

在您的情况下,如果您只想显示成功/错误消息,我认为您不需要使用自定义指令。


首先,您应该将相关的表单字段包装在单个模态对象中,而不是多个模态对象中。喜欢:

<input type="text" name="name" ng-model="person.name">

<input type="text" name="occupation" ng-model="person.occupation">

其次,您应该使用ng-submitng-click进行表单提交操作,例如:

<input type="submit" id="submit" value="Submit" ng-click="doSubmit(person)">

<form ng-submit="doSubmit(person)">
    ...
    <input type="submit" id="submit" value="Submit">
</form>

第三,您应该使用ng-model从表单中获取数据而不是serialize()。就像在How can I post data as form data instead of a request payload?中讨论的那样:

$scope.doSubmit = function(formData) {    // use `=` instead of `:` here
    $http({
        method: "POST",
        url: "/save",
        data: $.param(formData),
        headers: {'Content-Type': 'application/x-www-form-urlencoded'}
    })
    // ...
}

最后,如果您希望向用户显示除文字以外的一些反馈,则应尽可能使用ng-showng-switchng-classng-style。喜欢:

<span class="name-error" ng-show="errorMessage.name" ng-bind="errorMessage.name"></span>

当您要显示名称错误消息时,在fail()回调中:

errorMessage.name = "Some error message here.";  // don't forget to initialize errorMessage to an empty object

那就是它!


<强>更新

对于您在评论中提出的问题,我认为,在Angular中,人们可能更喜欢对单个DOM元素或嵌套指令使用单独的内聚指令,然后将它们与模型或控制器(嵌套指令)连接起来。

在您的示例中,我建议您使用两者的组合。

首先,为UI用途使用一组嵌套指令。您可能有一个绑定到body标签的指令并访问那里的视口信息。然后,您可以使用require: '^ParentDirective'在内部指令中访问它。

然后,您可以将模型绑定到内部指令。因此,您将数据和UI操作分开。

e.g。

<body auto-size-messages>
    <div ng-repeat="message in messages" message="message"></div>
</body>

auto-size-messages中,您将获得视口属性并将其分配给控制器。在message中,您操纵DOM以将消息放在所需位置,并根据消息属性显示内容。

您可以参考https://docs.angularjs.org/guide/directive中的创建包含其他元素的指令部分来了解嵌套指令。