David Brower
David Brower

Reputation: 3048

Problem preventing evaluation of AngularJS expression when bound with ng-model

I have a problem with a web page that is rendered using the ASP.NET MVC (5.2.3) razor engine but which also uses AngularJS (1.7.4). The problem is that what should be rendered as plain text is being evaluated by AngularJS.

So, for example, in our model we have a property Name that when the value is, for example, {{1 + 1}} is being displayed as 2 i.e. the AngularJS expression is being evaluated:

enter image description here

The (redacted) cshtml page is along the following lines:

@model Models.SomeViewModel

<div ng-controller="RuleController" ng-form="ruleForm" novalidate>
  <!-- stuff here -->
   <div class="panel">
      <div class="panel-heading">
       <!-- stuff here -->
      </div>
    <div class="panel-body ng-cloak">
        <!-- stuff here -->
        <div class="row form-group">
            @Html.LabelFor(model => model.Name, new HtmlAttributeBuilder().WithCssClass("col-sm-1  control-label"))
            <div class="col-xs-12 col-sm-10 col-md-11 pull-right">
                @Html.TextBoxFor(model => model.Name, new HtmlAttributeBuilder().WithCssClass("form-control form-group-margin").WithNgModel("viewModel.name").WithNgChange("updateName(viewModel.name)").WithRequired())
                <span id="name-error" class="text-danger error-text" ng-model="errors.viewModel.Name">{{errors.viewModel.Name}}</span>
            </div>
        </div>

The C# class that is referenced in the Razor view - HtmlBuilder - inherits from `Dictionary'

[Serializable]
public class HtmlAttributeBuilder : Dictionary<string, object>
{
    public HtmlAttributeBuilder WithCssClass(string cssClassName)
    {
        this.Add("class", cssClassName);
        return this;
    }

    public HtmlAttributeBuilder WithNgModel(string property)
    {
        this.Add("ng-model", property);
        return this;
    }

    public HtmlAttributeBuilder WithNgChange(string val)
    {
        this.Add("ng-change", val);
        return this;
    }
}

Interestingly, when I look at the value of $scope.viewModel.name in the RuleController I can see that it is {{1 + 1}} and not 2.

I have tried using ng-non-bindable and while it prevents evaluation of the Angular expression it also prevents persisted updates to the value as it removes two-way binding.

Upvotes: 0

Views: 126

Answers (1)

Jorge Salazar
Jorge Salazar

Reputation: 11

Have you tried this directive?

https://docs.angularjs.org/api/ng/directive/ngNonBindable

Note, this should probably go in the comments, but I don't have enough reputation.

Upvotes: 1

Related Questions