2017-04-26 59 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