0

サーバーからメタデータを取得し、フォームを動的に構築する動的フォーム ディレクティブを構築しました。レンダリングされた入力はModel、メタデータとは別のオブジェクトにバインドされます。それを達成するために、私たちは次のようなことをしています:

<input type="field.Type" 
       ng-model="Model[field.Name]" 
       ng-repeat="field in metadata.Fields" />

上記のマークアップが機能し (単純なシナリオでは機能します)、バインディングが期待どおりに機能すると仮定します。残念ながら、使用しているモデルがスカラー プロパティのコレクションではない場合、すべてがうまくいきません。例は次のとおりです。

  • メジャー.ID
  • ディメンション[0].SelectedAttribute

ご覧のとおり、ネストされたプロパティがある場合、および/またはバインドする必要があるリストがある場合に問題が発生しますModel[propertyName]。動的バインディングを実現するために表記法を使用しているため、これは明らかに正常な動作です。

サーバーからの式を自分で解析し、モデルの階層 (ネストされたプロパティ) をたどり、バインディングを理解することを考えましたが、(まだ) 正しく理解できませんでした。さらに、リスト/配列バインディングの問題を解決する時間についてはまだ何も考えていません。

何かご意見は?

4

2 に答える 2

2

モデルからリスト プロパティを取得しようとしているのか、 Dynamic Set Modelを作成しようとしているのかよくわかりません。

リスト プロパティについては、モデルに配列を追加するか、リスト プロパティを持つオブジェクトを追加するだけで、それほど難しくありません。


複数のモデル

それとも、複数の「モデル」を使用しようとしていますか?

function MyCtrl($scope, $filter) 
{        
    $scope.Model = { 
        SubModel : {
             // Submodel stuff
        },

        FooModel : {
             // Submodel stuff
        }
    }
}

編集:

私は最初の試みで質問のポイントを完全に見逃していました。質問は、プロパティのタイプに基づいて異なるコンテンツをレンダリングすることを本当に望んでいました (それがあなたが望んでいたものでない場合は、申し訳ありません)プランカーの例

HTML

<div ng-app ng-controller="MyCtrl">
  <div ng-if="Configuration.hasLevels">
    <div ng-repeat="lvl in Configuration.levels">
      <input type="textbox" value="{{lvl.severity}}">
      {{lvl.name}}
    </div>
  </div>
  <div ng-if="!Configuration.hasLevels">
    no levels: {{Configuration.levels}}
  </div>
</div>

JavaScript

function MyCtrl($scope, $filter) 
{
  // Configuration Object
  $scope.Configuration = {
    debug : true,
    // Log Levels
    levels : [
      new Level("log", 0),
      new Level("warning", 1),
      new Level("error", 2)
    ]
    // levels : "hello world"
  };

  $scope.Configuration.hasLevels = ($scope.Configuration.levels instanceof Array);
}

function Level(name, severity) { this.name = name; this.severity = severity; }
于 2013-09-12T14:47:17.177 に答える
0

そのため、HTMLテンプレートを使用する代わりに、JavaScriptコードでHTMLを作成する必要がありました...そのようなもの:

FormBuilder.prototype.getAtomField = function (field) {
    var self = this;
    var atom = '<atom type="field.Type" name="field.Title" data-ng-show="field.Visible || evaluateExpression(field.VisibleIf)" hidevalidation="field.HideValidation" withlabel="field.WithLabel"'
     + 'datavalue="' + self.getDataValueBindingExpression(field.Name) + '" class="field.ClassName" required="field.Required || evaluateExpression(field.RequiredIf)"'
     + 'enabled="(field.Enabled || evaluateExpression(field.EnabledIf))" watermark="field.Watermark" orientation="field.Orientation" example="field.Example" modelkey="api.getFieldModelKey(field.Name)"'
     + 'min="field.Min" max="field.Max" description="field.Description" suggestedvalues="field.SuggestedValues" limittosuggestions="field.LimitToSuggestions" multiple="field.Multiple"'
     + 'displaypath="field.DisplayPath" valuepath="field.ValuePath" remoteurl="field.RemoteUrl" changehandler="invokeAction" changehandlerparam="field.ChangeHandler"'
     + 'source="field.Source" sourcefilter="field.SourceFilter" groupnamepath="field.GroupNamePath" disabledpath="field.DisabledPath" iconpath="field.IconPath"'
     + 'toggle="field.Toggle" formatresult="field.FormatResult" formatselection="field.FormatSelection" requestdatamapper="field.RequestDataMapper"'
     + 'responsedatamapper="field.ResponseDataMapper" pagelimit="field.PageLimit" remotedatatype="field.RemoteDataType" eagersearch="field.EagerSearch"'
     + 'numberofdigits="field.NumberOfDigits" step="field.Step" format="api.evaluateRegexExpression(field.Format, field.Type)"></atom>';
    return atom;
};

atomこれは、フォーム フィールドと同等の単なるラッパー ディレクティブであることに注意してください。ここでトリックを行う部分self.getDataValueBindingExpression(field.Name)は、連結されたフィールド名を適切に返すだけの呼び出しです。

FormBuilder.prototype.getDataValueBindingExpression = function (name) {
    var self = this;
    return 'api.description.Model.' + name;
};
于 2013-09-17T06:05:50.907 に答える