AngularJS - объект не передан в модальный диалог

0

У меня проблема с приложением AngularJS, которое я делаю. Он отображает список контактов, и для каждого контакта есть кнопка, после чего нажатие кнопки модально появляется с формой. Эта форма должна показывать существующую контактную информацию, и если вы хотите что-то изменить, введите новую информацию и нажмите "Отправить".

Проблема, однако, в том, что существующая информация не отображается в форме, поэтому ее редактирование не работает. Я предполагаю, что проблема в том, что модальная не наследует область действия с родительской страницы, но я не знаю, что делать, чтобы исправить это. Я попытался сыграть с атрибутами полей ввода (например, добавив ng-model от $ parent и определяя значение ng-init), но безрезультатно, поэтому я надеюсь, что некоторые из экспертов здесь смогут указать меня на правильном пути.

Заранее спасибо.

Теперь позвольте мне показать вам мой код, чтобы вы могли видеть контекст, о котором я говорю. Вот 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>

И 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 -->

И, наконец, соответствующие части контроллера:

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();
}]);
Теги:
angularjs-scope

1 ответ

0
Лучший ответ

Модаль не имеет той же области действия, что и таблица контактов, поскольку каждый раз, когда Angular находит другую директиву ng-controller, она создает новую область.

Вы объявляете ng-scope как в таблице контактов, так и в модальном, что вызывает угловое создание разных областей.

См. Этот ответ для получения дополнительной информации:
qaru.site/questions/121935/...

Есть несколько способов решить эту проблему...

1) Поместите модальный HTML внутри родительского элемента, где вы уже объявляете ng-controller в первый раз - таким образом он будет частью той же области

2) директивы модальный Использование UI Bootstrap для создания модальных с собственным контроллером и передать в $scope.contact от вашего contactsController. См. Пример здесь
https://angular-ui.github.io/bootstrap/#/modal

3) Создайте службу, которая хранит $scope.contact и вводит это в отдельный контроллер, который вы создаете для модального. Здесь кто-то другой скрипка показывает это:
http://jsfiddle.net/whnSs/

  • 0
    Большое спасибо за это! Это очень помогает. В качестве быстрого (и, возможно, грязного) исправления я назначил contact в $rootScope , но в долгосрочной перспективе я бы предпочел реализовать 2) или 3) из вашего списка.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню