lcaaroe
lcaaroe

Reputation: 85

AngularJS 1.6.5 How to avoid executing angular expression in 'value' of input field

I use ASP.NET MVC with AngularJS 1.6.5.

In a Razor view, I have the following input:

<input id="live-search-input" 
  class="live-search__input"
  type="search"
  name="search"
  autocomplete="off"
  ng-model="searchTerm"
  ng-model-options="{debounce: 500}"
  ng-click="resultsClick($event)"
  value="@Model.Search"
/>

The Model.Search value comes from the backend, and represents the user input. ASP.NET MVC takes care of a bunch of standard encoding/sanitizing, so I couldn't, for example, search for html tags. However, I don't have any server side validation to check for something that is an Angular expression (i.e. an expression surrounded by {{double curly brackets}})

So, if I searched for {{1+2}}, the above input field would evaluate the expression to "3", and the input field displays that I searched for "3", rather than what I actually searched for: "{{1+2}}":

Search box after post

Angular provides the ngNonBindable directive, which essentially tells Angular to not compile the content of the element. However, this doesn't help me make the 'value' attribute of my input field non-bindable. Do I have to sanitize this input server side (implementing my own sanitizer for angular expressions), or is there an 'angular' way to do it, similar to using ngNonBindable?

Upvotes: 0

Views: 381

Answers (1)

lenilsondc
lenilsondc

Reputation: 9800

Actually you have to remove Razor from the playground, angularjs is supposed to take care of the frontend aspect, it includes not depending on serverside bindings. You should make an http request in order to populate your form with ng-model instead.

However, if you insist in use angularjs this way, you can use a custom directive to set the ngModel value. The following snippet implements a directive that aims input tags with ng-model on it and sets the evaluated value of the value attribute in the ng-model property.

angular.module('app', [])
  .directive('input', function($parse) {
    return {
      restrict: 'E',
      require: 'ngModel',
      link: function(scope, element, attrs, ngModelCtrl) {
        // retrieve ngModel getter & setter
        var modelGetter = $parse(attrs['ngModel']);
        var modelSetter = modelGetter.assign;

        // observe attrs evaluation
        attrs.$observe('value', function(value) {
          // use model setter to set the view value of the ngModel
          modelSetter(scope, value);
        });
      }
    };
  });
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.6/angular.js"></script>
<div ng-app="app">
  <h1>{{ name }}</h1>
  <input type="text" ng-model="name" value="{{ 'Chuck Norris' }}">
</div>

I strongly advise you to use http api based approach, mixing serverside with angularjs templates drives your code to disorder, and it's also a waste of serverside processing.

Upvotes: 1

Related Questions