I know you have commented saying you want to avoid "watch". Please tell why?. I have seen usage of watch in the directives hence my solution is as below.
<div ng-app="myApp" ng-controller="myCtrl">
<div>
<input type="text" ng-model="newFruit">
<button ng-click="addFruit()">Add</button>
</div>
<input type="text" ng-allowed-vals="fruits" ng-model="fruit">
</div>
angular.module("myApp", []);
angular.module("myApp")
.controller("myCtrl", ["$scope", function($scope){
$scope.fruits = ["apple"];
$scope.fruit = "";
$scope.addFruit = function(){
$scope.fruits.push($scope.newFruit);
$scope.newFruit = "";
}
}]);
angular.module("myApp")
.directive("ngAllowedVals", [function () {
return {
restrict: "A",
require: "ngModel",
scope: {
ngAllowedVals: "="
},
link: function (scope, ele, attr, ngModelCtrl) {
scope.$watch("ngAllowedVals", function(old, val){
ngModelCtrl.$setViewValue(formatArr(scope.ngAllowedVals));
ngModelCtrl.$render();
}, true);
function formatArr(allowedVals){
if(!allowedVals.length) return "";
var result = "";
for(var i = 0; i < allowedVals.length; i++){
if(i < allowedVals.length - 1)
result += "'" + allowedVals[i] + "',";
else
result += "'" + allowedVals[i] + "'";
}
return "[" + result + "]";
}
}
}
}]);
JSFiddle