我已创建codepen来显示问题。
使用服务appModalService
时,vm
对象会直接替换为FormController
对象,因此vm
的所有属性都无法在模板中访问与vm
对象关联的控制器变得完全没用。
appModalService
上的讨论(推理)可以在ionic form中找到。
我在这里添加了代码以供参考。有关解决此问题的任何建议吗?
HTML:
<html ng-app="ionicApp">
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
<title>Ionic modal service</title>
<link href="http://code.ionicframework.com/nightly/css/ionic.css" rel="stylesheet">
<script src="http://code.ionicframework.com/nightly/js/ionic.bundle.js"></script>
</head>
<body ng-controller="AppCtrl as vm">
<ion-content padding="true" ng-class="{'has-footer': showFooter}">
<div class="row">
<div class="col">
<button ng-click="vm.showNonWorkingForm()" class="button button-assertive button-block">
Show Non Working Form (using appModalService)
</button>
</div>
</div>
<div class="row">
<div class="col">
<button ng-click="vm.showWorkingForm()" class="button button-assertive button-block">
Show Working Form (using ionic ModalService)
</button>
</div>
</div>
</ion-content>
<script id="non-working-form-modal.html" type="text/ng-template">
<ion-modal-view>
<ion-header-bar class="bar bar-header bar-positive">
<h1 class="title">Form</h1>
<button class="button button-clear button-primary" ng-click="vm.closeModal()">Close</button>
</ion-header-bar>
<ion-content>
<form novalidate name="vm.f" ng-submit="vm.submit()">
<div class="list">
<label class="item item-input">
<input placeholder="text" type="text" name="sometext" ng-model="vm.sometext" required>
</label>
</div>
<button type="submit" class="button button-block">
Submit
</button>
</form>
{{ vm }}
</ion-content>
</ion-modal-view>
</script>
<script id="working-form-modal.html" type="text/ng-template">
<div class="modal" ng-controller="WorkingCtrl as vm">
<ion-header-bar class="bar bar-header bar-positive">
<h1 class="title">Form</h1>
<button class="button button-clear button-primary" ng-click="closeModal()">Close</button>
</ion-header-bar>
<ion-content>
<form novalidate name="vm.f" ng-submit="vm.submit()">
<div class="list">
<label class="item item-input">
<input placeholder="text" type="text" name="sometext" ng-model="vm.sometext" required>
</label>
</div>
<button type="submit" class="button button-block">
Submit
</button>
</form>
{{ vm }}
</ion-content>
</div>
</script>
</body>
</html>
JS
angular.module('ionicApp', ['ionic'])
.controller('NonWorkingCtrl', ['$scope', 'parameters', function($scope, parameters) {
var vm = this;
/* placeholder for the FormController object */
vm.f = null;
vm.sometext = 'Added Some text';
vm.submit = function() {
if (vm.f.$valid) {
alert('NonWorkingCtrl Valid');
} else {
alert('NonWorkingCtrl InValid');
}
}
/* additional fields */
vm.field1 = 'field1';
vm.field2 = 'field2';
vm.field3 = 'field3';
vm.field4 = 'field4';
vm.field5 = 'field5';
vm.field6 = 'field6';
vm.field7 = 'field7';
}])
.controller('WorkingCtrl', ['$scope', function($scope) {
var vm = this;
/* placeholder for the FormController object */
vm.f = null;
vm.sometext = 'Added Some text';
vm.submit = function() {
if (vm.f.$valid) {
alert('WorkingCtrl Valid');
} else {
alert('WorkingCtrl InValid');
}
}
/* additional fields */
vm.field1 = 'field1';
vm.field2 = 'field2';
vm.field3 = 'field3';
vm.field4 = 'field4';
vm.field5 = 'field5';
vm.field6 = 'field6';
vm.field7 = 'field7';
}])
.controller('AppCtrl', ['$scope', 'appModalService', '$ionicModal', function($scope, appModalService, $ionicModal) {
var vm = this;
vm.showNonWorkingForm = function() {
appModalService.show('non-working-form-modal.html', 'NonWorkingCtrl as vm');
};
vm.showWorkingForm = function() {
$ionicModal.fromTemplateUrl('working-form-modal.html', {
scope: $scope,
animation: 'slide-in-up'
}).then(function(modal) {
$scope.modal = modal;
$scope.modal.show();
});
$scope.closeModal = function() {
$scope.modal.hide();
$scope.modal.remove();
};
}
}])
.factory('appModalService', ['$ionicModal', '$rootScope', '$q', '$injector', '$controller', function($ionicModal, $rootScope, $q, $injector, $controller) {
return {
show: show
}
function show(templeteUrl, controller, parameters, options) {
// Grab the injector and create a new scope
var deferred = $q.defer(),
ctrlInstance,
modalScope = $rootScope.$new(),
thisScopeId = modalScope.$id,
defaultOptions = {
animation: 'slide-in-up',
focusFirstInput: false,
backdropClickToClose: true,
hardwareBackButtonClose: true,
modalCallback: null
};
options = angular.extend({}, defaultOptions, options);
$ionicModal.fromTemplateUrl(templeteUrl, {
scope: modalScope,
animation: options.animation,
focusFirstInput: options.focusFirstInput,
backdropClickToClose: options.backdropClickToClose,
hardwareBackButtonClose: options.hardwareBackButtonClose
}).then(function(modal) {
modalScope.modal = modal;
modalScope.openModal = function() {
modalScope.modal.show();
};
modalScope.closeModal = function(result) {
deferred.resolve(result);
modalScope.modal.hide();
};
modalScope.$on('modal.hidden', function(thisModal) {
if (thisModal.currentScope) {
var modalScopeId = thisModal.currentScope.$id;
if (thisScopeId === modalScopeId) {
deferred.resolve(null);
_cleanup(thisModal.currentScope);
}
}
});
// Invoke the controller
var locals = {
'$scope': modalScope,
'parameters': parameters
};
var ctrlEval = _evalController(controller);
ctrlInstance = $controller(controller, locals);
if (ctrlEval.isControllerAs) {
ctrlInstance.openModal = modalScope.openModal;
ctrlInstance.closeModal = modalScope.closeModal;
}
modalScope.modal.show()
.then(function() {
modalScope.$broadcast('modal.afterShow', modalScope.modal);
});
if (angular.isFunction(options.modalCallback)) {
options.modalCallback(modal);
}
}, function(err) {
deferred.reject(err);
});
return deferred.promise;
}
function _cleanup(scope) {
scope.$destroy();
if (scope.modal) {
scope.modal.remove();
}
}
function _evalController(ctrlName) {
var result = {
isControllerAs: false,
controllerName: '',
propName: ''
};
var fragments = (ctrlName || '').trim().split(/\s+/);
result.isControllerAs = fragments.length === 3 && (fragments[1] || '').toLowerCase() === 'as';
if (result.isControllerAs) {
result.controllerName = fragments[0];
result.propName = fragments[2];
} else {
result.controllerName = ctrlName;
}
return result;
}
}]);
答案 0 :(得分:0)
@NEB我在离子形式方面遇到了类似的问题。我在IonicForum DiscGolfer17
上找到了here的答案基本上,离子的<content>
指令创建了它自己的孤立范围。正如形式和离子的<ion-modal-view>
指令一样,我相信。
为了让您的ng-click="vm.closeModal()"
工作,您需要在$parent
前面vm
链接ng-click="$parent.vm.closeModal()"
这告诉它继承它的父母$scope
。这是working fork of your Plunk