如何使用变量将对象键传递给Angular Directive?

时间:2013-07-17 17:52:21

标签: angularjs codemirror

我正在使用Code Mirror指令将文本区域格式化为代码。

工作原理:

<textarea ui-codemirror type="textarea" ng-model="x"></textarea>

您可以像这样设置选项

<textarea ui-codemirror="editorOptions" type="textarea" ng-model="x"></textarea>

并在您的控制器中:

$scope.editorOptions = {
            name: 'javascript',
            json: true,
            smartIndent: false,
            tabSize: 2,
            lineWrapping : true,
            lineNumbers: true,
            mode: 'javascript'
        }

什么行不通:

我正在尝试根据模型的另一部分动态更改editorOptions(我支持Javascript和Markdown)。

所以我正在尝试这个:

$scope.editorOptions = {
        json: {
            name: 'javascript',
            json: true,
            smartIndent: false,
            tabSize: 2,
            lineWrapping : true,
            lineNumbers: true,
            mode: 'javascript'
        },
        markdown: {
            name: 'markdown',
            json: false,
            smartIndent: false,
            tabSize: 2,
            lineWrapping : true,
            lineNumbers: true,
            mode: 'markdown'
        }
    };

然后在HTML中:

<select ng-model='editorType' required ng-options='option.value as option.name for option in editorTypes'></select>
<textarea ui-codemirror="editorOptions[editorType]" type="textarea" ng-model="x"></textarea>

我的问题是 - 如何使用select模型(editorType)的值来指定在代码镜像指令中使用哪些选项对象?

我试过

<textarea ui-codemirror="editorOptions.[editorType]" type="textarea" ng-model="x"></textarea>
<textarea ui-codemirror="editorOptions[$scope.editorType]" type="textarea" ng-model="x"></textarea>

一切都无济于事。

任何人都知道这样做的正确方法是什么?

很多,非常感谢!

更新 我相信这是正确的语法:

ui-codemirror="editorOptions[editorType]".

我认为指令没有意识到变量已经改变了。

2 个答案:

答案 0 :(得分:3)

我不认为这会在不使用ui-codemirror的情况下对你有用。 UI-codemirror中的代码在开头有opts = angular.extend({}, options, scope.$eval(attrs.uiCodemirror));,但它不会监视更新。

如果您从:https://github.com/angular-ui/ui-codemirror/blob/master/ui-codemirror.js分叉ui-codemirror,然后添加类似

的内容
attrs.$observe('uiCodemirror', function (newVal, oldVal) {
  if (newVal !== oldVal) {
    opts = angular.extend({}, options, scope.$eval(attrs.uiCodemirror));
    codeMirror = CodeMirror.fromTextArea(elm[0], opts); //or maybe $timeout(deferredCodemirror) ??
  }
});

然后它可能会工作,但我没有测试过,所以我不知道它是否真的有效。也许这会让你知道如何创建你需要的指令。

另一个可能相当重的替代方案是实例化两个代码错误并在两者之间切换......但我真的不太喜欢这个选项。

答案 1 :(得分:1)

添加到Jonathan的回复中:

attrs.$observe('uiCodemirror', function (newVal, oldVal) 
{
  if(newVal !== oldVal) 
  {
    opts = angular.extend({}, options, scope.$eval(attrs.uiCodemirror));
    var keys = Object.keys(opts)
    if(keys.length != 0)
    {
      keys.forEach(function(i)
      {
        var v = opts[i];
        codeMirror.setOption(i, v);
      });

      $timeout(function() { codeMirror.refresh()} );
    }
  }
});