简体   繁体   English

使用ng-options和ng-selected进行角度选择

[英]Angular select using ng-options and ng-selected

I am having an issue with a select. 我在选择时遇到问题。 I have a profile view that utilizes the profileCtrl. 我有一个使用profileCtrl的配置文件视图。 In that controller I get the users info from the db and put it into scope. 在该控制器中,我从数据库获取用户信息并将其放入范围。 I also use a service to grab all the info from the config table in the db and insert that into rootScope. 我还使用一项服务来获取db中config表中的所有信息,并将其插入rootScope中。 My question and answers come from the config table (rootScope) the user's selected answer comes from the user info (scope). 我的问题和答案来自配置表(rootScope),用户选择的答案来自用户信息(作用域)。 I need a select that preselects whatever answer the user has in the db. 我需要一个选择,可以预先选择用户在数据库中具有的任何答案。 Below is my code. 下面是我的代码。

Profile Controller: 配置文件控制器:

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: (I have condensed the code to be read easily) 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>

Alright, so I made a plunk, and this is what I came up with. 好吧,所以我做了个小菜一碟,这就是我想出的。 This will set the select option if the professor's current answer exists in the list. 如果教授的当前答案在列表中,则将设置选择选项。

The reason ng-init didn't work is because the selectedAnswer model is actually expecting to see an object with property 'answer'. ng-init无效的原因是因为selectedAnswer模型实际上期望看到具有“ answer”属性的对象。 In other words, selectedAnswer is the entire object, not just the answer itself. 换句话说,selectedAnswer是整个对象,而不仅仅是答案本身。

https://plnkr.co/edit/CRraZXY2jsmiV1oJx6VN?p=preview 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
   });

-- Old Answer -- -旧答案-

Have you tried ng-init? 您是否尝试过ng-init?

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

I have made a very complex plunkr, I was a bit slower than @brianslattery I guess. 我做了一个非常复杂的插件,我觉得比@brianslattery慢一点。

Here's my take: https://plnkr.co/edit/5fnB6oWrZ9WhujN7eH0T?p=preview 这是我的看法: 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>

The app will look something like this: 该应用程序将如下所示:

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];
      });
    }
  }

});

There are several issues to consider. 有几个问题要考虑。 NgOptions likes to use objects rather than values. NgOptions喜欢使用对象而不是值。 Also, your 'ng repeat' is calling for profs[0] instead of using the now repeated profiles variable. 同样,您的“ ng repeat”正在调用profs [0],而不是使用现在重复的profiles变量。

Other issue to consider is that your 'answer' would not be 'profile dependent', but will be one for the entire scope, I'm pretty sure that is NOT what you want. 要考虑的另一个问题是,您的“答案”将不会与“配置文件相关”,而是整个范围内的答案,我很确定这不是您想要的。

So, the plunkr I created makes individual answers for each. 因此,我创建的the客为每个人做出了单独的答案。 It also takes into account the possibility of getting either the profiles first or the available answers first, no matter which comes first, which is, I believe, Important. 它也考虑了不管是先出现的(我相信这是重要的),无论是先获得配置文件还是先获得可用答案的可能性。

Let me know if this helps. 让我知道是否有帮助。 Best regards, 最好的祝福,

Rafa. 拉法

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM