Используйте пользовательский источник данных в шаблоне пользовательского интерфейса angular
-
26-12-2019 - |
Вопрос
Я использую пользовательский интерфейс-bootstrap-tpls чтобы отобразить datepicker в моем угловом представлении.Я настроил шаблон таким образом :
customDatePicker.html
<script id="template/datepicker/day.html" type="text/ng-template">
<table role="grid" aria-labelledby="{{uniqueId}}-title" aria-activedescendant="{{activeDateId}}">
<thead>
<tr>
<th>
<button type="button" class="btn btn-default btn-sm pull-left" ng-click="move(-1)" tabindex="-1">
<i class="glyphicon glyphicon-chevron-left"></i>
</button>
</th>
<th colspan="{{5 + showWeeks}}">
<button id="{{uniqueId}}-title" role="heading" aria-live="assertive" aria-atomic="true" type="button" class="btn btn-default btn-sm" ng-click="toggleMode()" tabindex="-1" style="width:100%;">
<strong>{{title}}</strong>
</button>
</th>
<th>
<button type="button" class="btn btn-default btn-sm pull-right" ng-click="move(1)" tabindex="-1">
<i class="glyphicon glyphicon-chevron-right"></i>
</button>
</th>
</tr>
<tr>
<th ng-show="showWeeks" class="text-center"></th>
<th ng-repeat="label in labels track by $index" class="text-center">
<small aria-label="{{label.full}}">{{label.abbr}}</small>
</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="row in rows track by $index">
<td ng-repeat="dt in row track by dt.date" class="text-center" role="gridcell" id="{{dt.uid}}" aria-disabled="{{!!dt.disabled}}">
<button type="button" style="width:100%;" class="btn btn-default btn-sm" ng-click="select(dt.date); openCustomDialog(dt.date)" ng-disabled="dt.disabled" tabindex="-1">
<span>{{dt.label}}</span>
</button>
</td>
</tr>
</tbody>
</table>
</script>
<datepicker ng-model="dt" min-date="minDate" show-weeks="true" class="well well-sm"></datepicker>
Все работает нормально.Проблема, с которой я сталкиваюсь, заключается в том, что я должен использовать пользовательские данные в шаблоне в
<tbody>
<tr ng-repeat="row in rows track by $index">
<td ng-repeat="dt in row track by dt.date" class="text-center" role="gridcell" id="{{dt.uid}}" aria-disabled="{{!!dt.disabled}}">
<button type="button" style="width:100%;" class="btn btn-default btn-sm" ng-click="select(dt.date); openCustomDialog(dt.date)" ng-disabled="dt.disabled" tabindex="-1">
<span>{{dt.label}}</span>
</button>
</td>
</tr>
</tbody>
НапримерЯ должен добавить класс (чтобы изменить цвет) для какого-то события.
Пожалуйста, помогите.
Решение
Это лучше всего решить с помощью директивы, вставленной в шаблон.(Вот обновленный поршень) Обратите внимание на highlight-day="dt"
директива вставлена сюда.Это внесет каждый день в нашу пользовательскую директиву, чтобы определить, нужно ли нам выделять этот день.Я предпочитаю этот метод выделения, в отличие от выполнения операции на стороннем javascript.
<button highlight-day="dt" ng-class="{selected: dt.highlighted}" type="button" style="width:100%;" class="btn btn-default btn-sm" ng-click="select(dt.date); openCustomDialog(dt.date)" ng-disabled="dt.disabled" tabindex="-1">
<span>{{dt.label}}</span>
</button>
Как только мы это получим, мы можем добавить директиву, которая выглядит следующим образом.Обратите внимание, что вся логика выполняется в link
функция.
app.directive("highlightDay", ["myCustomObj", "monthMapper", function(myCustomObj, monthMapper){
return {
restrict: "A",
//This brings the value of attribute into our current scope as an object, not just a DOM string
scope: {
highlightDay: "="
},
link: function(scope, element, attrs, ctrls) {
//Make the native date object as a local variable
var dt = scope.highlightDay.date;
//Find out what the month name should be
var monthName = monthMapper[dt.getMonth()];
//Loop through all the possible selected dates
for(var i in myCustomObj){
var entry = myCustomObj[i];
//If the month and day match
var isMatch = entry.month === monthName && entry.day === dt.getDate();
if(isMatch) {
scope.highlightDate.highlighted = isMatch
break;
}
}
}
};
}]);
Вы также замечаете две другие зависимости, myCustomObj
и monthMapper
.Они определены в другом месте angular и могут быть такими, как я сделал ниже.
app.constant("monthMapper", [
"january",
"february",
"march",
"april",
"may",
"june",
"july",
"august",
"september",
"november",
"december"
]);
app.value("myCustomObj", [{
"month" : 'june',
"day" : 19
},
{
"month" : 'june',
"day" : 28
}
]);
В качестве дополнительного примечания, вы могли бы ускорить время определения того, следует ли выбирать день, путем реорганизации myCustomObj
может быть, что-то вроде этого.
{
june: [19, 28]
}
Другие советы
I think that the best and fastest way to change the template is first copy the same template and make the adjustments on him as the template already has all the events and necessary classes binded.
The second solution for you is to take all the parts of ng-{{event}} (ng-class, ng-click, ng-...) and to connect them to your template in the same place.
Hope it make sense to you.