2015-11-04 90 views
0

我创建了一个codepen来显示问题。Ionic:自定义模态窗体的控制器中的对象访问

当服务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

@NEB。我在IonicForum上找到了我的答案DiscGolfer17here

基本上,离子的<content>指令创建它自己的隔离范围。我相信,正如形式和离子的指令<ion-modal-view>一样。

所以让你ng-click="vm.closeModal()"工作,你需要到链$parentvm面前这样ng-click="$parent.vm.closeModal()"

这告诉它继承它的父母$scope。这里是一个working fork of your Plunk

+0

感谢您的$父'信息,但即使如此我无法访问控制器中的窗体对象'vm.f'([见链接](http://codepen.io/nebben/pen/WQLweO?editors = 101))作为参考'vm'将在控制器中有所不同。此外,我没有看到你在共享的Plunk中使用了'$ parent'。我终于用'createModal'修补'$ ionicModalParams'作为'$ ionicModalParams',以在给定''templateString'上使用'$ controller'将控制器和额外的'params'关联起来。 – NEB