簡體   English   中英

嘗試在 SharePoint 環境中使用 AngularJS DateRangePicker 時出現未定義錯誤

[英]Getting undefined error trying to use AngularJS DateRangePicker in SharePoint environment

我正在嘗試使用 AngularJS 日期范圍選擇器根據日期范圍過濾數據。 我無法弄清楚為什么我會收到 TypeError "Cannot read property 'startDate' of undefined。在 angularjs controller 的頂部附近我正在定義日期 ZA8CFDE6331BD59EB2AC96F8911C4B6使用 SharePoint?如何解決此問題以在 SharePoint 中工作。該代碼在具有本地 json 文件的 LAMP 堆棧中運行良好,但在 SP.20 上無法運行。謝謝您。

以下是我如何在 html 文件的頭部引入所有依賴項。

<head>
    <title>Rolling Log</title>
    <meta charset="uft-8">
    <link rel="stylesheet" href="css/bootstrap.min.css">
    <link rel="stylesheet" href="css/daterangepicker.css" />
    <link rel="stylesheet" href="css/styles.css">
    <script src="js/jquery-3.4.1.min.js"></script>
    <script src="js/bootstrap.min.js"></script>
    <script src="js/angular.js"></script>
    <!-- <script src="js/angular-route.js"></script> -->
    <script src="js/moment.js"></script>
    <script src="js/daterangepicker.js"></script>
    <script src="js/angular-daterangepicker.js"></script>
</head>

這是 html 文件的主體:

<body ng-app="myApp" ng-controller="myController" ng-clock>
    <nav class="navbar navbar-expand-md bg-dark navbar-dark">
      ...
    </nav>

<div class="wrapper">
    <div><h1>CM Rolling Log</h1></div>
<div id="top">
    <hr>
<span style="float: right; padding: 2px;">Search: <input type="text" ng-model="searchText"></span>
<label class="my-auto mr-2">Date Opened:</label>
<input date-range-picker class="form-control" ng-model="datePicker.date" clearable="true" style="max-width: 280px;">
 <table>
  <tr>
   <th ng-click="sortBy('timestamp')" width="10%">Date Time</th>
   <th ng-click="sortBy('Action')" width="70%">Action</th>
   <th ng-click="sortBy('AO')" width="15%">AO</th>
  </tr>
  <tr ng-repeat="item in log | orderBy:sortField:reverseOrder | filter:searchText | myfilter: datePicker.date">
    <td>{{item.timestamp | date: 'MM/dd/yyyy HH:MM'}}</td>
    <td>{{item.Action | removeHTMLTags | strip }}</td>
    <td>{{item.AO}}</td>
  </tr>
</table>
</div>

<div id="bottom">
  <form action="" method="POST" ng-submit="createFunc()">
    <br /><span id="user"></span> <br /> <br />
    Comment: <br /> <textarea  id="action" rows="5" cols="130" name="comment"></textarea> <br /><br />
    <input type="submit" name="submit_btn" value="Post comment">
  </form>
</div>
</div>

帶有應用日期范圍選擇器的 angularjs 代碼位於底部。

var app = angular.module('myApp', ['daterangepicker']);

app.filter('removeHTMLTags', function() {
    return function(text) {
        return text ? String(text).replace(/<[^>]+/gm, '') : '';
    }
});

app.controller('myController',
    function($scope, $http) {

        $http({
            method: 'GET',
            url: "https://.../_api/web/lists/GetByTitle('RollingLog')/items?$top=1000&$select=timestamp,Action,AO",
            headers: {"Accept": "application/json;odata=verbose"}
        }).then(function (data, status, headers, config) {
            $scope.log = data.data.d.results;

            $scope.datePicker = { date: {
                startDate: null, endDate: null
            } };

            $scope.searchText = "";
            $scope.reverseOrder = true;
            $scope.sortField = "timestamp";
            $scope.sortBy = function(sortField) {
                $scope.reverseOrder = ($scope.sortField === sortField) ? !$scope.reverseOrder : false;
                $scope.sortField = sortField;
            };

            jQuery.ajax({
                url: "https://.../_api/web/currentuser?$select=Title",
                type: "GET",
                headers: {"Accept": "application/json;odata=verbose","Content-Type": "application/json;odata=verbose"},
                success: function(data) {
                    username = data.d.Title;
                    console.log("user name: " + username);
                    document.getElementById("user").innerHTML = username;
                },
                error: function(data) {
                    console.log("Error occurred trying to get user id");
                }
            });
        }, function errorCallback(response) {

        });

        $scope.getFormDigest = function() {
            console.log("Inside getFormDigest");
            var formdigest;

            jQuery.ajax({
                url: "https://.../_api/contextinfo",
                type: "POST",
                async: false,
                headers: {
                    "accept": "application/json;odata=verbose",
                    type: "POST"
                },
                success: function(data)
                {   
                    console.log(typeof data);
                    formdigest = data.d.GetContextWebInformation.FormDigestValue
                }
            });
            return formdigest;
        };

        $scope.createFunc = function() {
            console.log("Inside createFunc...");
            var dt = new Date();
            var action = document.getElementById("action").value;
            var formdigest = $scope.getFormDigest();

            jQuery.ajax({
                url: "https://.../_api/web/lists/GetByTitle('RollingLog')/items",
                method: "POST",
                data: JSON.stringify({
                    '__metadata' : {'type': 'SP.Data.RollingLogListItem'},
                    'Action': action,
                    'AO': username,
                    'timestamp': dt
                }),
                headers: {
                    "accept": "application/json;odata=verbose",
                    "content-type": "application/json;odata=verbose",
                    "X-RequestDigest": formdigest
                },
                success: function(data) {
                    console.log("entry created successfully...");
                },
                error: function(data) {
                    console.log(("#__REQUESTDIGEST").val());
                    console.log("Error message: " + JSON.stringify(data.responseJSON.error));
                }
            });
        };
    }
).filter('strip', function() {
    return function(str) {
        return str.replace(/>/g, '').replace(/&#160/g, ' ').replace(/>/g, '').replace(/>>/g, '').replace(/;/g, '').replace(/#/g, '"').replace(/&quot/g,'"');
    }
});

app.filter("myfilter", function() {
    return function(items, date) {
        if (!date.startDate || !date.endDate) {
            return items
        }
        startDate = moment(date.startDate);
        endDate = moment(date.endDate);
        return items.filter(function(elem) {
            var openedDate = moment(elem.date_opened);
            return startDate.diff(openedDate, 'days') <= 0 && endDate.diff(openedDate, 'days') >= 0;
        });
    };
});

當您的 promise 被解析(在“then”內)時,您正在初始化您的 datepicker,因此在此之前您的 datepicker 是未定義的,因此您會收到“Cannot read property 'startDate' of undefined”錯誤。 你可以

1)將您的初始化代碼移動到 controller 的開頭

app.controller('myController',
    function($scope, $http) {
            $scope.datePicker = { date: {
                startDate: null, endDate: null
            } };
            ...

2)或者您可以在過濾器中添加 null 控件

app.filter("myfilter", function() {
    return function(items, date) {
        if(date == undefined){
            return items;
        }
        if (!date.startDate || !date.endDate) {
            return items
        }
        startDate = moment(date.startDate);
        endDate = moment(date.endDate);
        return items.filter(function(elem) {
            var openedDate = moment(elem.date_opened);
            return startDate.diff(openedDate, 'days') <= 0 && endDate.diff(openedDate, 'days') >= 0;
        });
    };
});

為了消除此類錯誤,我將使用ng-if到 promise 過濾器接收帶有datedatePicker

我相信您不想顯示表格行 ae 來調用ng-repeat直到datePicker.date被初始化。

<tr ng-if="datePicker && datePicker.date"
    ng-repeat="item in log | orderBy:sortField:reverseOrder | filter:searchText | myfilter: datePicker.date">
</tr>

在這種情況下,一旦myfilter undefined並且它已經與摘要周期同步,將調用datePicker.date ,因此您不需要額外的觀察者。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM