0

I’m new to Angularjs and the Dojo-Toolkit so please forgive my newbieness.
I have an element in my page that I’m able to bind to my model without any problem: <input type="text" ng-model="startDateRange"></input> This works as expected.

When I update the element so it uses the Dojo-Toolkit the binding appears to be broken: <input type="text" ng-model="startDateRange" data-dojo-type="dijit/form/DateTextBox"></input> The binding to the model no longer works.

I’m not sure what I’m doing wrong. Any help would be appreciated. Thanks.

Aaron Benzel
  • 311
  • 1
  • 4
  • 11

2 Answers2

1

AngularJS binding works upon DOM nodes, if you move, delete or replace a DOM node that AngularJS is watching, then the code will no longer work.

As Thomas Kagan said, Dojo widgets will replace the DOM node with the data-dojo-type on it by the DOM nodes provided in the template of those widgets. This simply erases your binding as if it didn't exist.

A proper AngularJS solution would be to wrap the Dojo DateTextBox inside a directive, so AngularJS knows that this is encapsulated and AngularJS should only access the directive through an API (the scope of a directive).

For example:

myApp.directive("dateTextBox", function($timeout) {
  var link = function(scope, elem, attr) {
    require(["dijit/form/DateTextBox"], function(DateTextBox) {
      var dateTxtBox = new DateTextBox({});
      dateTxtBox.set('value', scope.date);
      dateTxtBox.on("change", function(date) {
        $timeout(function() {
          scope.date = date;
        });
      });
      elem.append(dateTxtBox.domNode);
    });
  };

  return {
    restrict: 'E',
    scope: {
      date: "="
    },
    link: link
  };
});

This is just a basic example, I also made a demo, which you can view by running the snippet below.

angular.module("myApp", []).controller("TestCtrl", function($scope) {
  $scope.date = new Date();
})

.directive("dateTextBox", function($timeout) {
  var link = function(scope, elem, attr) {
    require(["dijit/form/DateTextBox"], function(DateTextBox) {
      var dateTxtBox = new DateTextBox({});
      dateTxtBox.set('value', scope.date);
      dateTxtBox.on("change", function(date) {
        $timeout(function() {
          scope.date = date;
        });
      });
      elem.append(dateTxtBox.domNode);
    });
  };
  
  return {
    restrict: 'E',
    scope: {
      date: "="
    },
    link: link
  };
});
<!DOCTYPE html>
<html>

  <head>
    <link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.1/dijit/themes/claro/claro.css" />
    <script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.1/dojo/dojo.js"></script>
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.26/angular.min.js"></script>
    <script src="script.js"></script>
  </head>

  <body ng-app="myApp" class="claro">
    <div ng-controller="TestCtrl">
      <date-text-box date="date"></date-text-box><br />
      {{date | date}}
    </div>
  </body>

</html>
g00glen00b
  • 41,995
  • 13
  • 95
  • 133
0

When the dojo parser runs it will identify the input element as a dijit widget and destroy your input element replacing it with a dojo widget so the ng-model property will no longer be present. I recommend using Dojo's observable module for data-binding instead of trying to mix in angular

Thomas Kagan
  • 440
  • 3
  • 16