2017-04-26 125 views
0

我有一个订阅功能,通过检查收音机框打开。当在这部分内部打开时,我有2个单选按钮用于订阅每周或每月一次的项目。当我按保存这个时期的状态必须从服务器保存一个项目。您可以查看截图以查看view。无论如何,没有保存,因为数组结果为空,该项目不在该数组中。我的问题是我看到下面的项目,但不知何故,我没有将它推入到数组中,并使用从单选按钮中选择的时间段。我希望得到帮助,以了解为什么这样做以及我应该修改哪些内容以使其正常工作。AngularJS:需要解决空阵列的bug

请查看我共享控制器和视图代码:

searchApp.controller('UserSettingsCtrl', ['$scope', '$q', '$rootScope', 'aiStorage', 'userConfig', 'UserSettingsService', 'WebsiteSource', 'AnalyticsEmailService', 'toaster', '$translate', '$filter', 'ngTableParams', 
function($scope, $q, $rootScope, store, userConfig, UserSettingsService, WebsiteSource, AnalyticsEmailService, toaster, $translate, $filter, ngTableParams) { 
    $scope.init = function() { 
     $scope.availableLanguages = { 
      da: 'Dansk', 
      en: 'English', 
      sv: 'Svensk' 
     } 
     window.scope = $scope 
     $scope.userInfo = store.get('user') 
     $scope.loadingAction = false 
     $scope.selectFlag = false 
     $scope.subscriptionEnginesFromServer = [] 
     $scope.subscriptionEngines = [] 
     $scope.analyticsEmailSettings = {} 
     $scope.engines = angular.copy(WebsiteSource.sites) 
     AnalyticsEmailService.getUserSubscription().then(
      function success(response) { 
       $scope.loadingAction = false 
       $scope.subscription = response 
       console.log('response.data', response.data) 
       $scope.subscriptionEnginesFromServer = populateSubscribedEnginesFromServer(response.data) 
       getUnselectedEngines() 
       $scope.analyticsEmailSettings.subscribed = (response.data.length > 0) 
      }, 
      function error() {}) 
    } 

    function populateSubscribedEnginesFromServer(data) { 
     console.log('data', data) 
     var subscriptionEngines = [] 
     for (var i = 0; i < data.length; i++) { 
      var subscription = data[i] 
      var engine = $scope.engines.filter(function(x) { 
       if (x.id === subscription.engine) { 
        var index = $scope.engines.indexOf(x) 
        $scope.engines[index].type = subscription.type 
       } 

       return x.id === subscription.engine 
      })[0] 
      console.log('engine', engine) 
      if (engine) subscription.name = engine.name 

      subscriptionEngines.push(subscription) 
     } 
     console.log('subscriptionEngines', subscriptionEngines) 
     if (subscriptionEngines.length == 0) { 
      $scope.analyticsEmailSettings.subscription = 'WeeklyAnalytics' 
     } else { 
      $scope.analyticsEmailSettings.subscription = subscriptionEngines[0].type 
     } 
     return subscriptionEngines 
    } 

    // Save for all always the user have to press the save button if wants save no auto save as it is now 
    $scope.save = function() { 
      $scope.loadingAction = true 
      if ($scope.analyticsEmailSettings.subscribed) { 
       AnalyticsEmailService.updatesubscriptions($scope.subscriptionEnginesFromServer, function success(response) {}, function error() {}) 
      } else { 
       $scope.analyticsEmailSettings.subscription = 'WeeklyAnalytics' 
       $scope.subscriptionEnginesFromServer = [] 
       AnalyticsEmailService.updatesubscriptions($scope.subscriptionEnginesFromServer, function success(response) {}, function error() {}) 
      } 
      UserSettingsService.save({ 
       userId: $scope.userInfo.id 
      }, $scope.userInfo, function() { 
       $scope.loadingAction = false 
       userConfig.setCurrentUserConfig($scope.userInfo) 
       userConfig.setUserLocale() 
       store.set('user', $scope.userInfo) 
       toaster.pop({ 
        type: 'success', 
        body: $translate.instant('notifications_user_settings_changed_success') 
       }) 
      }, function() {}) 
      $scope.subscriptionEngines = [] 
     } 
     // removeSelectedEngines 
    getUnselectedEngines = function() { 
     for (var i = 0; i < $scope.engines.length; i++) { 
      if ($scope.subscriptionEnginesFromServer.filter(function(x) { 
        return x.engine === $scope.engines[i].id 
       }).length == 0) 
       $scope.engines[i].type = '' 
     } 
    } 

    // @todo: consider referring by array key instead of engineId 
    function updatesubscriptions(engineId, subscriptionType) { 
     var engine 
     for (var i = 0; i < $scope.subscriptionEnginesFromServer.length; i++) { 
      if ($scope.subscriptionEnginesFromServer[i].engine == engineId) { 
       engine = $scope.subscriptionEnginesFromServer[i] 
      } 
     } 

     engine.type = subscriptionType 
     engine.engine = engineId 
    } 

    $scope.updateSubscriptionType = function(engine) { 
     for (var i = 0; i < $scope.subscriptionEnginesFromServer.length; i++) { 
      updatesubscriptions($scope.subscriptionEnginesFromServer[i].engine, $scope.analyticsEmailSettings.subscription) 
     } 
    } 

    $scope.addSubscribedEngine = function(engine) { 
     $scope.subscriptionEngines = [] 
     engine.type = $scope.analyticsEmailSettings.subscription 

     $scope.subscriptionEnginesFromServer.push({ 
      type: engine.type, 
      engine: engine.id, 
      name: engine.name 
     }) 
    } 

    $scope.selectFirstUnsubscribedEngine = function() { 
     var filtered 
     filtered = $scope.engines.filter(function(x) { 
      return x.type == '' 
     }) 

     filtered = $filter('orderBy')(filtered, 'name') 

     $scope.engine.current = filtered.length ? filtered[0] : null 
    } 

    $scope.removeSubscribedEngine = function(engine) { 
     engine.type = '' 
     for (var i = 0; i < $scope.subscriptionEnginesFromServer.length; i++) { 
      if ($scope.subscriptionEnginesFromServer[i].engine == engine.id) { 
       $scope.subscriptionEnginesFromServer.splice(i, 1) 
      } 
     } 
     save() 
    } 
}]) 

查看:

<div ng-controller="UserSettingsCtrl" ng-init="init()"> 

<div class="content"> 

    <header class="flex-container row header"> 
     <div class="flex-1"> 
      <h1 class="flex-1">{{ 'user_settings_title' | translate }}</h1> 
     </div> 
     <!--<a class="logout" href ui-sref="account.settings.changepassword">{{ 'user_change_password_menu' | translate }}</a>--> 
    </header> 

    <div class="main-edit"> 
     <div class="subsection"> 
      <div class="inputs-container-row full-width"> 
       <div class="input-group full-width"> 
        <div class="inputfield"> 
         <label class="label ng-binding" for="name"> 
          {{ 'user_settings_firstname_label' | translate }} 
         </label> 
         <input type="text" name="firstname" ng-model="userInfo.firstName" class="flex-1" ng-class="{'first-letter-to-upper' : userInfo.firstName.length > 0 }" placeholder="{{ 'user_settings_firstname_placeholder' | translate }}"> 
        </div> 
       </div> 
       <div class="input-group full-width"> 
        <div class="inputfield"> 
         <label class="label ng-binding" for="name"> 
          {{ 'user_settings_lastname_label' | translate }} 
         </label> 
         <input type="text" name="lastname" ng-model="userInfo.lastName" class="flex-1" ng-class="{'first-letter-to-upper' : userInfo.lastName.length > 0 }" placeholder="{{ 'user_settings_lastname_placeholder' | translate }}"> 
        </div> 
       </div> 
      </div> 
      <div class="inputs-container-row full-width"> 
       <div class="inputs-container-row half-width"> 
        <div class="input-group full-width"> 
         <label class="label" for="name">{{ 'user_settings_language_label' | translate }}</label> 
         <div class="select-group full-width"> 
          <select class="select" id="selectLanguage" ng-model="userInfo.language" ng-options="key as value for (key , value) in availableLanguages"></select> 
          <label for="selectLanguage"><span class="fa fa-angle-down"></span></label> 
         </div> 
        </div> 
       </div> 
       <div class="inputs-container-row half-width"> 
        <div class="input-group full-width"> 
         <label class="label" for="name"> 
          {{ 'user_settings_phone_label' | translate }} 
         </label> 
         <input type="text" name="lastname" ng-model="userInfo.phoneNumber" placeholder="{{ 'user_settings_phone_placeholder' | translate }}"> 
        </div> 
       </div> 
      </div> 
     </div> 
     <div class="subsection"> 
      <div class="inputs-container-row half-width"> 
       <div class="input-group full-width"> 
        <label class="label" for="name"> 
         {{ 'user_settings_password_label' | translate }} 
         <a ui-sref="account.settings.changepassword" class="button button-link--primary button--first"> 
          {{ 'user_settings_password_button' | translate }}... 
         </a> 
        </label> 
       </div> 
      </div> 
     </div> 
    </div> 
    <div class="flex-container row header"> 
     <div class="flex-1"> 
      <h1 class="flex-1">{{ 'user_settings_emailStatistics_title' | translate }}</h1> 
     </div> 
    </div> 
    <!--||| Subscribe Start |||--> 
    <div class="main-edit"> 
     <div class="subsection"> 
      <div class="flex-container row"> 
       <div class="radiobutton-group"> 
        <div class="width-140"> 
         <input id="subscribed" type="checkbox" ng-model="analyticsEmailSettings.subscribed" value="subscribed" class="radiobutton"> 
         <label class="label highlight inline no-bottom-margin" for="subscribed"> 
          {{ 'user_settings_emailStatistics_subscribe' | translate }} 
         </label> 
        </div> 
       </div> 
      </div> 
      <div ng-show="analyticsEmailSettings.subscribed"> 
       <div class="flex-container row"> 
        <div class="input-group flex-1" ng-switch="analyticsEmailSettings.subscription"> 
         <label class="label" for="name">{{ 'user_settings_emailStatistics_recurrence' | translate }}</label> 
         <div class="inputs-container-row half-width" name="oftenReportSent"> 
          <span class="radiobutton flex-1" ng-class="{'checked' : analyticsEmailSettings.subscription === 'WeeklyAnalytics'}" name="radio"> 
           <input type="radio" name="WeeklyAnalytics" ng-model="analyticsEmailSettings.subscription" ng-change="updateSubscriptionType()" ng-checked="analyticsEmailSettings.subscription === 'WeeklyAnalytics'" value="WeeklyAnalytics" id="WeeklyAnalytics" ng-required=""> 
           <label for="WeeklyAnalytics">{{ 'user_settings_emailStatistics_weekly' | translate }}</label> 
          </span> 
          <span class="radiobutton flex-1" ng-class="{'checked' : analyticsEmailSettings.subscription === 'MonthlyAnalytics'}"> 
           <input type="radio" name="MonthlyAnalytics" ng-model="analyticsEmailSettings.subscription" ng-change="updateSubscriptionType()" ng-checked="analyticsEmailSettings.subscription === 'MonthlyAnalytics'" value="MonthlyAnalytics" id="MonthlyAnalytics" ng-required=""> 
           <label for="MonthlyAnalytics">{{ 'user_settings_emailStatistics_monthly' | translate }}</label> 
          </span> 
         </div> 
         <div> <span style="color:red;" ng-show="analyticsEmailSettings.subscription == null">Please select option</span></div> 
        </div> 
       </div> 
       <h1>Before</h1> 
       <div ng-if="engines.length == 1"> 
        <ul class="tags tags--inline item-with-inline-buttons"> 
         <li ng-repeat="engine in engines | orderBy:'name'"> 
          {{engine.name}} 
          <span class="button-icon button--primary button--delete" ng-click="removeSubscribedEngine(engine); selectFirstUnsubscribedEngine()"> 
           <i class="fa fa-trash-o"></i> 
          </span> 
         </li> 
        </ul> 
       </div> 
       <h1>after</h1> 
       <div ng-show="engines.length > 1"> 
        <div class="flex-container row" ng-show="((engines | filter:{type:''}:true).length != 0)"> 
         <div class="input-group full-width"> 
          <label class="label" for="selectEngine"> 
          {{ 'user_settings_emailStatistics_engines_label' | translate }}: 
         </label> 
          <div class="half-width inputfield--horizontal" style="margin-bottom: 10px;"> 
           <div class="full-width select-group" ng-if="(engines | filter:{type:''}:true).length > 0"> 

            <select class="select" id="selectEngine" ng-model="$parent.engine.current" ng-options="website.name for website in engines | filter:{type:''}:true | orderBy:'name'" ng-init="$parent.engine.current = (engines | filter:{type:''}:true | orderBy:'name')[0]"> 
           </select> 
            <label for="selectSubscription"><span class="fa fa-angle-down"></span></label> 
           </div> 
           <span ng-show="engines.length == 1">{{(engines | filter:{type:''}:true)[0].name}}</span> 
           <div id="btnAddWebSitesSubscription" ng-show="engines.length > 0" class="button button--add" ng-click="addSubscribedEngine(engine.current); selectFirstUnsubscribedEngine()"><i class="fa fa-plus"></i></div> 
          </div> 
         </div> 
        </div> 
        <div ng-model="successMessage" ng-show="showMessage" style="color:green;" class="message fadein fadeout">{{successMessage}}</div> 
       </div> 
       <h1 ng-show="subscriptionEnginesFromServer.length > 0 && engines.length > 1">Websites Subscribed</h1> 
       <div class="flex-container row" ng-if="subscriptionEnginesFromServer.length > 0 && engines.length > 1"> 
        <ul class="tags tags--inline item-with-inline-buttons"> 
         <li ng-repeat="engine in engines | filter:{type:'Analytics'} | orderBy:'name'"> 
          {{engine.name}} 
          <span class="button-icon button--primary button--delete" ng-click="removeSubscribedEngine(engine); selectFirstUnsubscribedEngine()"> 
           <i class="fa fa-trash-o"></i> 
          </span> 
         </li> 
        </ul> 
       </div> 
      </div> 
     </div> 
     <footer class="flex-container flex-end row footer"> 
      <button class="button button--primary button--action" ng-click="save();"> 
        <i ng-show="loadingAction" class="fa fa-spinner fa-spinner-custom"></i> 
        <span ng-show="!loadingAction">{{ 'general_save' | translate }}</span> 
      </button> 
     </footer> 
    </div> 
</div> 

回答

0

小心使用NG隐藏/ NG秀当的部分是'隐藏'它破坏了模型(如果有)包含在它自己内部(所以,使用ng-if代替)。

在认购板块的HTML,您拨打一个电话这样的:

ng-change="updateSubscriptionType()" 

但在你的JavaScript您有:

$scope.updateSubscriptionType = function(engine) { 
    for (var i = 0; i < $scope.subscriptionEnginesFromServer.length; i++) { 
    updatesubscriptions($scope.subscriptionEnginesFromServer[i].engine, $scope.analyticsEmailSettings.subscription) 
    } 
} 

因此它期待的“引擎”的说法,这你永远不会通过。但是看看代码,你不会使用引擎参数;你使用$ scope.subscriptionEnginesFromServer [i]的'engine'属性,但就是这样。

但是,无论如何,它不会做我能看到的任何事情。它通过一个空数组循环,然后调用updatesubscriptions()来做某件事,但它实际上不会调用它。

另外,updatesubscriptions()方法本身并不实际执行任何操作。这可能就是为什么你没有在你的数组中获得任何东西。我建议稍微修改你的模板,因为订阅单选按钮不在引擎循环中,所以你将无法将订阅类型与任何引擎相关联。一旦你这样做,那么订阅键入单选按钮将有机会获得“引擎”,你可以在通过相应地修改方法:

$scope.updateSubscriptionType = function(engine) { 
    if (!$scope.subscriptionEnginesFromService.includes(engine)) { 
    $scope.subscriptionEnginesFromService.push(engine); 
    } 
    updatesubscriptions(engine, $scope.analyticsEmailSettings.subscription); 
} 

而且还修改updatesubscriptions()略。

+0

谢谢你的解释。你能告诉我,如果我理解的很好;所以你的意思是我必须在我的方法populateSubscribedEnginesFromServer(data)中传递引擎?所以我必须改变数据或添加引擎?你可以举个例子,或者告诉我你认为我应该修改哪种方法。 – Jakub

+0

嗨@rrd请问你有什么可能回答我,我仍然坚持这一点。我想知道我必须通过那个引擎,因为我试图通过不同的方法,但没有成功。请给我一个例子:)感谢您的帮助 – Jakub

+0

我会更新我的回复Jakub – rrd