【问题标题】:Angular select using ng-options and ng-selected使用 ng-options 和 ng-selected 进行角度选择
【发布时间】:2016-05-25 16:03:57
【问题描述】:

我在选择时遇到问题。我有一个使用 profileCtrl 的配置文件视图。在该控制器中,我从数据库中获取用户信息并将其放入范围。我还使用一项服务从数据库中的配置表中获取所有信息并将其插入到 rootScope 中。我的问题和答案来自配置表(rootScope)用户选择的答案来自用户信息(范围)。我需要一个选择来预先选择用户在数据库中的任何答案。下面是我的代码。

配置文件控制器:

app.controller('profileCtrl', function ($scope, $log, $http, $timeout, Data, Auth, dataShare, $sessionStorage, $rootScope, $confirm) {
    $timeout(function() {

      // get user's info from db and put it into scope
      Data.get('profile/'+$rootScope.user.uid).then(function(data){
        $scope.profs = data.data;
        $scope.buttonText = 'Update Profile';
      });

    }, 100);

    // get the configs from the configs service and put it in the rootScope
    dataShare.getconfigs().then(function(data){
        $rootScope.configs = data;

        // get the answers from the config table for the select's options
        $scope.availableAnswers = [
            { answer: $rootScope.configs[0].a1 }, 
            { answer: $rootScope.configs[0].a2 },
            { answer: $rootScope.configs[0].a3 }, 
            { answer: $rootScope.configs[0].a4 },
            { answer: $rootScope.configs[0].a5 }
          ];
    });

    // function executed on change from the select
    $scope.selectedItemChanged = function() {
      $log.log($scope.selectedAnswer);
    }

    // inline edit title
    $scope.updateUser = function(data) {
      Data.put('config/'+data.id, {profile_page_title:data.profile_page_title}).then(function (result) {
          Data.toast(result);
      });
    };

    $scope.saveProfile = function (profile) {

        profile.roles = $rootScope.user.roles;

        if(profile.uid.length > 0){
            Data.put('profile/'+profile.uid, profile).then(function (result) {
              $sessionStorage.user = profile;    
              $rootScope.user = $sessionStorage.user;
              Data.toast(result);
            });
        }else{
            Data.post('profile', profile).then(function (result) {
              $rootScope.name = profile.name
              Data.toast(result);
            });
        }

    };
});

HTML:(为了便于阅读,我已经压缩了代码)

<section class="row" id="" ng-repeat="profile in profs">
    <div class="col-xs-12" id="questionWidget">

      <h4>{{configs[0].question}}</h4>

      <!-- user's answer from db -->
      {{profs[0].answer}}

      <select ng-model="selectedAnswer" ng-change="selectedItemChanged()" ng-options="a.answer for a in availableAnswers">

      </select>

    </div>
</section>

【问题讨论】:

    标签: javascript angularjs


    【解决方案1】:

    好吧,所以我做了一个 plunk,这就是我想出的。如果教授的当前答案存在于列表中,这将设置选择选项。

    ng-init 不起作用的原因是 selectedAnswer 模型实际上希望看到一个具有属性“answer”的对象。换句话说,selectedAnswer 是整个对象,而不仅仅是答案本身。

    https://plnkr.co/edit/CRraZXY2jsmiV1oJx6VN?p=preview

        $scope.profs = [
            { answer: 'answer2' }
          ]
    
    
        $scope.availableAnswers = [
              { answer: 'answer1' },
              { answer: 'answer2' },
              { answer: 'answer3' },
            ];
    
    
       angular.forEach($scope.availableAnswers, function(availableAnswer){
    
         if ($scope.profs[0].answer === availableAnswer.answer)
          $scope.selectedAnswer = availableAnswer
       });
    

    -- 旧答案--

    你试过 ng-init 吗?

    ng-init="selectedAnswer = profs[0].answer"
    

    【讨论】:

    • 好的,我已经创建了一个有效的示例。这样能行吗?
    • 这是一件棘手的事情,因为它假定“同步”变量。一旦您介绍了可能尚未从数据库或 availableAnswers 中获取 profs 的事实,这种方法将不起作用。因此,您要么需要“观察”这些值,要么调用一个可以“了解”两个变量状态的函数,以便它们分配答案。
    【解决方案2】:

    我做了一个非常复杂的 plunkr,我猜我比 @brianslattery 慢了一点。

    这是我的看法: https://plnkr.co/edit/5fnB6oWrZ9WhujN7eH0T?p=preview

    <section class="row" id="" ng-repeat="profile in profs">
      <div class="col-xs-12" id="questionWidget">
    
        <h4>{{configs[0].question}}</h4>
    
        <!-- user's answer from db -->
        Answer: {{profile.answer}}<br>
    
        <select name="selector" ng-model="profile.answer" ng-change="selectedItemChanged(profile)" ng-options="a as a.answer for a in availableAnswers track by a.answer">
    
        </select>
    
      </div>
    </section>
    

    该应用将如下所示:

    var app = angular.module('plunker', []);
    
    app.controller('MainCtrl', function($rootScope, $scope, $timeout, $log, $filter) {
    
      $timeout(function() {
        // get user's info from db and put it into scope
        $scope.profs = [ { name: 'prof1', answer: 'a3' }, { name: 'prof2', answer: 'a2' } ];
        $scope.buttonText = 'Update Profile';
        appendAnswerObjects();
      }, 100);
    
      // get the configs from the configs service and put it in the rootScope
      $timeout(function(data){
        $rootScope.configs = [ { question: 'Question?', a1: 'a1', a2: 'a2', a3: 'a3', a4: 'a4', a5: 'a5' } ];
    
        // get the answers from the config table for the select's options
        $scope.availableAnswers = [
          { answer: $rootScope.configs[0].a1 }, 
          { answer: $rootScope.configs[0].a2 },
          { answer: $rootScope.configs[0].a3 }, 
          { answer: $rootScope.configs[0].a4 },
          { answer: $rootScope.configs[0].a5 }
        ];
    
        appendAnswerObjects();
      }, 200);
    
      // function executed on change from the select
      $scope.selectedItemChanged = function(profile) {
        $log.log(profile);
      }
    
      function appendAnswerObjects() {
        if($scope.profs && $scope.profs.length && $scope.availableAnswers && $scope.availableAnswers.length) {
          $scope.profs.forEach(function(profile) {
            profile.answer = $filter('filter')($scope.availableAnswers, { answer: profile.answer })[0];
          });
        }
      }
    
    });
    

    有几个问题需要考虑。 NgOptions 喜欢使用对象而不是值。此外,您的“ng 重复”正在调用 profs[0],而不是使用现在重复的 profiles 变量。

    需要考虑的另一个问题是,您的“答案”不会“依赖于个人资料”,而是适用于整个范围,我很确定这不是您想要的。

    所以,我创建的 plunkr 为每个人提供了单独的答案。它还考虑了先获取个人资料或先获取可用答案的可能性,无论哪个先出现,我认为这很重要。

    如果这有帮助,请告诉我。 最好的问候,

    拉法。

    【讨论】:

      最近更新 更多