AngularJS - 未传递给模态对话框的对象

时间:2015-07-01 14:30:31

标签: javascript angularjs angularjs-scope

我在使用AngularJS应用时遇到问题。它显示了一个联系人列表,每个联系人都有一个按钮,然后单击按钮,弹出一个带有表单的模式。此表单应显示现有的联系信息,如果您想更改某些内容,请键入新信息并按提交。

然而,问题是现有信息没有显示在表格中,因此编辑它并不起作用。我想问题是模式不会从父页面继承范围,但我不知道该怎么做才能解决这个问题。我试过在输入字段中使用属性(例如,通过$ parent预先设置ng-model。并定义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();
}]);

1 个答案:

答案 0 :(得分:0)

模态与contacts表没有共享相同的范围,因为每次Angular找到另一个ng-controller指令时,它都会创建一个新范围。

您在联系人表格和模式中声明ng-scope,这会导致角度创建不同的范围。

有关详细信息,请参阅此答案:
https://stackoverflow.com/a/14462341/4938335

有几种方法可以解决这个问题......

1)将模态HTML放在父元素中,您已经在第一次声明ng-controller - 这样它将成为同一范围的一部分

2)使用UI Bootstrap的模态指令生成具有自己的控制器的模态,并从$scope.contact传入contactsController。请参见此处的示例
https://angular-ui.github.io/bootstrap/#/modal

3)创建一个存储$scope.contact的服务,并将其注入您为模态创建的单独控制器中。这是别人的小提琴,表明了这一点:
http://jsfiddle.net/whnSs/