简体   繁体   English

AngularJS-对象未传递到模态对话框

[英]AngularJS - object not passed to modal dialog

I have a problem with an AngularJS app I'm making. 我正在制作的AngularJS应用程序有问题。 It shows a list of contacts, and for each contact there is a button whereupon clicking the button a modal pops up with a form. 它显示了一个联系人列表,每个联系人都有一个按钮,单击该按钮会弹出一个带有表单的模式。 This form should show the existing contact information, and if you want to change something you type the new information and press submit. 该表格应显示现有的联系信息,如果您要更改某些内容,请键入新信息,然后按提交。

The problem, however, is that the existing information is not shown in the form, hence editing it doesn't work. 但是,问题在于现有信息未显示在表单中,因此无法对其进行编辑。 I imagine that the issue is that the modal does not inherit the scope from the parent page, but I don't know what to do in order to fix that. 我想问题是模式不会从父页面继承作用域,但是我不知道该如何解决。 I have tried playing around with the attributes on the input fields (for example prepending ng-model by $parent. and defining an ng-init value), but to no avail, so I hope some of the experts here will be able to point me on the right track. 我尝试在输入字段上使用属性(例如,在$ parent之前添加ng-model并定义ng-init值),但无济于事,所以我希望这里的一些专家能够指出我走在正确的轨道上。

Thank you in advance. 先感谢您。

Now let me show you my code, so you can see the context I'm talking about. 现在,让我向您展示我的代码,以便您可以看到我正在谈论的上下文。 Here is the html that displays the list of contacts: 这是显示联系人列表的html:

<div class="panel panel-default" ng-controller="contactsController">
<div class="panel-body">
    <div id="gridContainer" ng-class="{'': state == 'list', 'none': state != 'list'}">
        <table class="table table-bordered table-striped">
            <thead>
            <tr>
                <th scope="col"><spring:message code="contacts.name"/></th>
                <th scope="col"><spring:message code="contacts.email"/></th>
                <th scope="col"><spring:message code="contacts.phone"/></th>
                <th scope="col"></th>
            </tr>
            </thead>
            <tbody>
            <tr ng-repeat="contact in page.source">
                <td class="tdContactsCentered">{{contact.name}}</td>
                <td class="tdContactsCentered">{{contact.email}}</td>
                <td class="tdContactsCentered">{{contact.phoneNumber}}</td>
                <td class="width15">
                    <div class="text-center">
                        <input type="hidden" value="{{contact.id}}"/>
                        <a ng-href="#updateContactsModal"
                           ng-click="selectedContact(contact);"
                           role="button"
                           title="<spring:message code="update"/>&nbsp;<spring:message code="contact"/>"
                           class="btn btn-sm btn-warning" data-toggle="modal">
                            <i class="icon-pencil"></i>
                        </a>
                        <a ng-href="#deleteContactsModal"
                           ng-click="selectedContact(contact);"
                           role="button"
                           title="<spring:message code="delete"/>&nbsp;<spring:message code="contact"/>"
                           class="btn btn-sm btn-danger" data-toggle="modal">
                            <em class="fa fa-trash"></em>
                        </a>
                    </div>
                </td>
            </tr>
            </tbody>
        </table>
    </div>
</div>

And the html that defines the modal and the form: 以及定义模态和形式的html:

<div id="updateContactsModal"
 class="modal fade centering"
 role="dialog"
 aria-labelledby="updateContactsModalLabel"
 aria-hidden="true" style="display: none;">
<div class="modal-dialog" role="document">
    <div class="modal-content">
<div class="modal-header">
    <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
    <h3 id="updateContactsModalLabel" class="modal-title">
        <spring:message code="update"/>&nbsp;<spring:message code="contact"/>
    </h3>
</div>
<div class="modal-body" data-ng-controller="contactsController">
    <form name="updateContactForm" novalidate>
        <input type="hidden"
               required
             data-ng-model="contact.id"
               name="id"
               value="{{contact.id}}"/>
        <div>
            <div class="form-group">
                    <label>* <spring:message code="contacts.name"/>:</label>
                    <input type="text"
                           autofocus
                           required
                           class="form-control"
                           data-ng-model="contact.name"
                           name="name"
                           placeholder="<spring:message code='contact'/>&nbsp;<spring:message code='contacts.name'/> "/>
                    <div>
                            <span class="alert alert-error"
                                  ng-show="displayValidationError && updateContactForm.name.$error.required">
                                <spring:message code="required"/>
                            </span>
                    </div>
            </div>
            <div class="form-group">
                    <label>* <spring:message code="contacts.email"/>:</label>
                <div class="input-append">
                    <input type="text"
                           required
                           class="form-control"
                           ng-model="contact.email"
                           name="email"
                           placeholder="<spring:message code='sample.email'/> "/>
                </div>
                    <div>
                            <span class="alert alert-error"
                                  ng-show="displayValidationError && updateContactForm.email.$error.required">
                                <spring:message code="required"/>
                            </span>
                    </div>
            </div>
            <div class="form-group">
                    <label>* <spring:message code="contacts.phone"/>:</label>
                <div class="input-append">
                    <input type="text"
                           required
                           class="form-control"
                           ng-model="contact.phoneNumber"
                           name="phoneNumber"
                           placeholder="<spring:message code='sample.phone'/> "/>
                </div>
                    <div>
                            <span class="alert alert-error"
                                  ng-show="displayValidationError && updateContactForm.phoneNumber.$error.required">
                                <spring:message code="required"/>
                            </span>
                    </div>
            </div>

        </div>
    </form>
    <div class="modal-footer">
        <input type="submit"
               class="btn btn-primary"
               ng-click="updateContact(updateContactForm);"
               value='<spring:message code="update"/>'/>
        <button class="btn btn-default"
                data-dismiss="modal"
                ng-click="exit('#updateContactsModal');"
                aria-hidden="true">
            <spring:message code="cancel"/></button>
    </div>
</div>

<span class="alert alert-error dialogErrorMessage"
      ng-show="errorOnSubmit">
    <spring:message code="request.error"/>
</span>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->

And finally the relevant parts of the controller: 最后是控制器的相关部分:

App.controller('contactsController', ["$scope", "$http", function($scope,$http) {

$scope.pageToGet = 0;

$scope.state = 'busy';

$scope.lastAction = '';

$scope.url = "/uaiContacts/protected/contacts/";

$scope.errorOnSubmit = true;
$scope.errorIllegalAccess = false;
$scope.displayMessageToUser = false;
$scope.displayValidationError = false;
$scope.displaySearchMessage = false;
$scope.displaySearchButton = false;
$scope.displayCreateContactButton = false;

$scope.contact = {};

$scope.searchFor = "";

$scope.getContactList = function () {
    var url = $scope.url;
    $scope.lastAction = 'list';

    $scope.startDialogAjaxRequest();

    var config = {params: {page: $scope.pageToGet}};

    $http.get(url, config)
        .success(function (data) {
            $scope.finishAjaxCallOnSuccess(data, null, false);
        })
        .error(function () {
            $scope.state = 'error';
            $scope.displayCreateContactButton = false;
        });
};

$scope.populateTable = function (data) {
    if (data.pagesCount > 0) {
        $scope.state = 'list';

        $scope.page = {source: data.contacts, currentPage: $scope.pageToGet, pagesCount: data.pagesCount, totalContacts : data.totalContacts};

        if($scope.page.pagesCount <= $scope.page.currentPage){
            $scope.pageToGet = $scope.page.pagesCount - 1;
            $scope.page.currentPage = $scope.page.pagesCount - 1;
        }

        $scope.displayCreateContactButton = true;
        $scope.displaySearchButton = true;
    } else {
        $scope.state = 'noresult';
        $scope.displayCreateContactButton = true;

        if(!$scope.searchFor){
            $scope.displaySearchButton = false;
        }
    }

    if (data.actionMessage || data.searchMessage) {
        $scope.displayMessageToUser = $scope.lastAction != 'search';

        $scope.page.actionMessage = data.actionMessage;
        $scope.page.searchMessage = data.searchMessage;
    } else {
        $scope.displayMessageToUser = false;
    }
};

$scope.exit = function (modalId) {
    $(modalId).modal('hide');

    $scope.contact = {};
    $scope.errorOnSubmit = false;
    $scope.errorIllegalAccess = false;
    $scope.displayValidationError = false;
};

$scope.finishAjaxCallOnSuccess = function (data, modalId, isPagination) {
    $scope.populateTable(data);
    $("#loadingModal").modal('hide');

    if(!isPagination){
        if(modalId){
            $scope.exit(modalId);
        }
    }

    $scope.lastAction = '';
};

$scope.startDialogAjaxRequest = function () {
    $scope.displayValidationError = false;
    $("#loadingModal").modal('show');
    $scope.previousState = $scope.state;
    $scope.state = 'busy';
};

$scope.handleErrorInDialogs = function (status) {
    $("#loadingModal").modal('hide');
    $scope.state = $scope.previousState;

    // illegal access
    if(status == 403){
        $scope.errorIllegalAccess = true;
        return;
    }

    $scope.errorOnSubmit = true;
    $scope.lastAction = '';
};

$scope.addSearchParametersIfNeeded = function(config, isPagination) {
    if(!config.params){
        config.params = {};
    }

    config.params.page = $scope.pageToGet;

    if($scope.searchFor){
        config.params.searchFor = $scope.searchFor;
    }
};

$scope.selectedContact = function (contact) {
    $scope.contact = angular.copy(contact);
    debugger;
};

$scope.updateContact = function (updateContactForm) {
    if (!updateContactForm.$valid) {
        debugger;
        $scope.displayValidationError = true;
        return;
    }

    $scope.lastAction = 'update';

    var url = $scope.url + $scope.contact.id;

    $scope.startDialogAjaxRequest();

    var config = {};

    $scope.addSearchParametersIfNeeded(config, false);

    $http.put(url, $scope.contact, config)
        .success(function (data) {
            $scope.finishAjaxCallOnSuccess(data, "#updateContactsModal", false);
        })
        .error(function(data, status, headers, config) {
            $scope.handleErrorInDialogs(status);
        });
};

$scope.getContactList();
}]);

The modal doesn't share the same scope as the contacts table because each time Angular finds another ng-controller directive, it creates a new scope. 模态与联系人表的作用域不同,因为Angular每次找到另一个ng-controller指令时,都会创建一个新的作用域。

You're declaring ng-scope in both the contacts table and the modal, which causes angular to create different scopes. 您在联系人表和模态中都声明了ng-scope ,这会导致angular创建不同的范围。

See this answer for more details: 查看此答案以获取更多详细信息:
https://stackoverflow.com/a/14462341/4938335 https://stackoverflow.com/a/14462341/4938335

There are a few ways to solve this... 有几种方法可以解决此问题...

1) Put the modal HTML inside the parent element where you're already declaring ng-controller the first time - that way it will be part of the same scope 1)将模式HTML放在您已经第一次声明ng-controller的父元素中-这样,它将属于同一范围

2) Use UI Bootstrap's modal directive to generate the modal with its own controller and pass in $scope.contact from your contactsController . 2)使用UI Bootstrap的modal指令生成带有其自己的控制器的modal,并从您的contactsController传递$scope.contact See example here 在这里查看示例
https://angular-ui.github.io/bootstrap/#/modal https://angular-ui.github.io/bootstrap/#/modal

3) Create a service that stores $scope.contact and inject that into a separate controller that you create for the modal. 3)创建一个存储$scope.contact的服务,并将其注入到为模态创建的单独控制器中。 Here's someone else's fiddle that shows this: 这是别人的小提琴显示出来的:
http://jsfiddle.net/whnSs/ http://jsfiddle.net/whnSs/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM