1

您好,我在使用 ko.toJSON 和 ko.mapping.toJSON 时遇到问题,在应用 google 地图绑定后返回无效状态错误。我应该将视图模型发布回 mvc 控制器。我设法在一个简单的视图模型中重现了这个问题。有没有办法去掉 googlemap 和标记,或者有其他方法吗?我究竟做错了什么?

<script src="/Scripts/knockout-2.3.0.debug.js"></script>
<script src="/Scripts/knockout.mapping-latest.debug.js"></script>
<script src="http://maps.googleapis.com/maps/api/js?sensor=false"></script>
<script type="text/javascript">
    function MyViewModel() {
        var self = this;
        self.test = ko.observable('Hello');
        self.mapOne = ko.observable({
            lat: ko.observable(12.24),
            lng: ko.observable(24.54)
        });

        self.mapTwo = ko.observable({
            lat: ko.observable(40.76),
            lng: ko.observable(-73.98)
        });

        self.save = function () {
            //Invalid state error occurs here!
            var jsonData = ko.toJSON(self);
        };
    }

    ko.bindingHandlers.map = {
        init: function (element, valueAccessor, allBindingsAccessor, viewModel) {
            var mapObj = ko.utils.unwrapObservable(valueAccessor());
            var latLng = new google.maps.LatLng(
                ko.utils.unwrapObservable(mapObj.lat),
                ko.utils.unwrapObservable(mapObj.lng));
            var mapOptions = {
                center: latLng,
                zoom: 6,
                mapTypeId: google.maps.MapTypeId.ROADMAP
            };

            mapObj.googleMap = new google.maps.Map(element, mapOptions);

            mapObj.marker = new google.maps.Marker({
                map: mapObj.googleMap,
                position: latLng,
                title: "You Are Here",
                draggable: true
            });

            mapObj.onChangedCoord = function (newValue) {
                var latLng = new google.maps.LatLng(
                    ko.utils.unwrapObservable(mapObj.lat),
                    ko.utils.unwrapObservable(mapObj.lng));
                mapObj.googleMap.setCenter(latLng);
            };

            mapObj.onMarkerMoved = function (dragEnd) {
                var latLng = mapObj.marker.getPosition();
                mapObj.lat(latLng.lat());
                mapObj.lng(latLng.lng());
            };

            mapObj.lat.subscribe(mapObj.onChangedCoord);
            mapObj.lng.subscribe(mapObj.onChangedCoord);

            google.maps.event.addListener(mapObj.marker, 'dragend', mapObj.onMarkerMoved);

            $("#" + element.getAttribute("id")).data("mapObj", mapObj);
        }
    };
    var viewModel = new MyViewModel();
    $(document).ready(function () {
        ko.applyBindings(viewModel);
    });
</script>

<div id="map1Div" data-bind="style: { width: '300px', height: '300px' }, map: mapOne"></div>
<input data-bind="value: mapOne().lat" />
<input data-bind="value: mapOne().lng" />
<button class="btn btn-primary" type="submit" data-bind="click: save">Save</button>

任何帮助,将不胜感激

4

1 回答 1

2

问题是由于将额外的 google maps 属性添加到原始 viewModel 引起的。当映射遇到它们时,它不知道该怎么办。如果它们被放置在一个单独的对象中,它似乎可以工作。mapObjVM是原始视图模型,mapObj是谷歌地图道具容器:

ko.bindingHandlers.map = {
    init: function (element, valueAccessor, allBindingsAccessor, viewModel) {
        var mapObjVM = ko.utils.unwrapObservable(valueAccessor());
        var mapObj = {};
        var latLng = new google.maps.LatLng(
            ko.utils.unwrapObservable(mapObjVM.lat),
            ko.utils.unwrapObservable(mapObjVM.lng));
        var mapOptions = {
            center: latLng,
            zoom: 6,
            mapTypeId: google.maps.MapTypeId.ROADMAP
        };

        mapObj.googleMap = new google.maps.Map(element, mapOptions);

        mapObj.marker = new google.maps.Marker({
            map: mapObj.googleMap,
            position: latLng,
            title: "You Are Here",
            draggable: true
        });

        mapObj.onChangedCoord = function (newValue) {
            var latLng = new google.maps.LatLng(
                ko.utils.unwrapObservable(mapObjVM.lat()),
                ko.utils.unwrapObservable(mapObjVM.lng()));
            mapObj.googleMap.setCenter(latLng);
        };

        mapObj.onMarkerMoved = function (dragEnd) {
            var latLng = mapObj.marker.getPosition();

            mapObjVM.lat(latLng.lat());
            mapObjVM.lng(latLng.lng());
        };

        mapObjVM.lat.subscribe(mapObj.onChangedCoord);
        mapObjVM.lng.subscribe(mapObj.onChangedCoord);

        google.maps.event.addListener(mapObj.marker, 'dragend', mapObj.onMarkerMoved);

        $("#" + element.getAttribute("id")).data("mapObj", mapObj);
    }
};
于 2013-11-08T15:57:03.943 回答