Очевидно, так происходит потому, что у variantId определен в scope уровнем выше, а директива вообще не создает изолированный scope, то есть использует тот, в котором директива вызвана. Соответственно, у них у всех один и тот же variantId. Проблема будет решена, если просто привязать сам объект к директиве, создав ей собственный scope:
{
restrict: 'AE',
templateUrl: '/admin/templates/template.html',
replace: false,
scope: { object: '=ngModel' } // что-то типа того
}
<template ng-model='VariantProperties[variantId]'></template>